/**\mainpage
 * Copyright (C) 2018 - 2019 Bosch Sensortec GmbH
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * Neither the name of the copyright holder nor the names of the
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
 * OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
 *
 * The information provided is believed to be accurate and reliable.
 * The copyright holder assumes no responsibility
 * for the consequences of use
 * of such information nor for any infringement of patents or
 * other rights of third parties which may result from its use.
 * No license is granted by implication or otherwise under any patent or
 * patent rights of the copyright holder.
 *
 * @file        bmi08a.c
 * @date        25 Sep 2019
 * @version     1.4.0
 *
 */

/*! \file bmi08a.c
 * \brief Sensor Driver for BMI08x family of sensors */

/****************************************************************************/

/**\name        Header files
 ****************************************************************************/
#include "bmi08x.h"

/****************************************************************************/

/** \name       Macros
 ****************************************************************************/
#if BMI08X_FEATURE_BMI085 == 1

/**\name    Value of LSB_PER_G = (power(2, BMI08X_16_BIT_RESOLUTION) / (2 * range)) */
#define LSB_PER_G UINT32_C(2048) /* for the 16-bit resolution and 16g range */
#elif BMI08X_FEATURE_BMI088 == 1

/**\name    Value of LSB_PER_G = (power(2, BMI08X_16_BIT_RESOLUTION) / (2 * range)) */
#define LSB_PER_G UINT32_C(1365) /* for the 16-bit resolution and 24g range */
#endif

/****************************************************************************/

/**\name        Local structures
 ****************************************************************************/

/*!
 * @brief Accel self test diff xyz data structure
 */
struct selftest_delta_limit
{
    /*! Accel X  data */
    uint16_t x;

    /*! Accel Y  data */
    uint16_t y;

    /*! Accel Z  data */
    uint16_t z;
};

/**\name Feature configuration file */
const uint8_t bmi08x_config_file[] = {
    0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x4b, 0x01, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00,
    0x2e, 0x80, 0x2e, 0xa7, 0x00, 0x80, 0x2e, 0x83, 0x00, 0x80, 0x2e, 0x15, 0x01, 0x50, 0x39, 0x21, 0x2e, 0xb0, 0xf0,
    0x10, 0x30, 0x21, 0x2e, 0x16, 0xf0, 0x80, 0x2e, 0x9c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xf6,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x50, 0x80, 0x7f,
    0xe7, 0x7f, 0xd5, 0x7f, 0xc4, 0x7f, 0xb3, 0x7f, 0xa2, 0x7f, 0x91, 0x7f, 0xf6, 0x7f, 0x7b, 0x7f, 0x00, 0x2e, 0x01,
    0x2e, 0x43, 0xf0, 0x08, 0xbc, 0x0f, 0xb8, 0x60, 0x7f, 0x00, 0x2e, 0x60, 0x6f, 0x00, 0xb2, 0x01, 0x2f, 0x98, 0x2e,
    0x12, 0xb2, 0x40, 0x30, 0x21, 0x2e, 0xb8, 0xf0, 0xf6, 0x6f, 0x91, 0x6f, 0xa2, 0x6f, 0xb3, 0x6f, 0xc4, 0x6f, 0xd5,
    0x6f, 0xe7, 0x6f, 0x7b, 0x6f, 0x80, 0x6f, 0x60, 0x5f, 0xc8, 0x2e, 0xa0, 0x50, 0x80, 0x7f, 0xe7, 0x7f, 0xd5, 0x7f,
    0xc4, 0x7f, 0xb3, 0x7f, 0xa2, 0x7f, 0x91, 0x7f, 0xf6, 0x7f, 0x7b, 0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x29, 0xf0, 0x08,
    0xbc, 0x0f, 0xb8, 0x60, 0x7f, 0x00, 0x2e, 0x60, 0x6f, 0x01, 0x90, 0x1b, 0x2f, 0x01, 0x2e, 0x02, 0x01, 0x0e, 0xbc,
    0x0e, 0xb8, 0x00, 0x90, 0x05, 0x2f, 0x01, 0x2e, 0x04, 0x01, 0x0f, 0xbc, 0x0f, 0xb8, 0x01, 0xb2, 0x0d, 0x2f, 0x01,
    0x2e, 0x63, 0x00, 0x01, 0x90, 0x04, 0x2f, 0x98, 0x2e, 0xa6, 0xb2, 0x00, 0x30, 0x21, 0x2e, 0x63, 0x00, 0x01, 0x2e,
    0x37, 0xf0, 0x21, 0x2e, 0x37, 0xf0, 0x02, 0x2d, 0x98, 0x2e, 0x7e, 0xb3, 0x80, 0x30, 0x21, 0x2e, 0xb8, 0xf0, 0xf6,
    0x6f, 0x91, 0x6f, 0xa2, 0x6f, 0xb3, 0x6f, 0xc4, 0x6f, 0xd5, 0x6f, 0xe7, 0x6f, 0x7b, 0x6f, 0x80, 0x6f, 0x60, 0x5f,
    0xc8, 0x2e, 0x40, 0x30, 0x21, 0x2e, 0xba, 0xf0, 0xb8, 0x2e, 0x80, 0x30, 0x21, 0x2e, 0xba, 0xf0, 0x10, 0x24, 0x80,
    0x00, 0x03, 0x2e, 0x06, 0xf0, 0x08, 0x0a, 0x21, 0x2e, 0x06, 0xf0, 0x00, 0x3e, 0x03, 0x2e, 0x06, 0xf0, 0x08, 0x08,
    0x51, 0x30, 0x01, 0x0a, 0x21, 0x2e, 0x06, 0xf0, 0xb8, 0x2e, 0x00, 0x31, 0x21, 0x2e, 0xba, 0xf0, 0xb8, 0x2e, 0xaa,
    0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0xed, 0x8f, 0xd9, 0x31, 0x00, 0x00, 0xc6, 0x01,
    0x8c, 0x03, 0xc6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10,
    0x00, 0x00, 0x00, 0x60, 0x50, 0xe7, 0x7f, 0xf6, 0x7f, 0x36, 0x30, 0x0f, 0x2e, 0x01, 0xf0, 0xfe, 0xbf, 0xfe, 0xbb,
    0xb7, 0x05, 0xa6, 0x7f, 0xd3, 0x7f, 0xc4, 0x7f, 0xb5, 0x7f, 0x14, 0x24, 0x89, 0xf0, 0x3f, 0x8b, 0x03, 0x41, 0x44,
    0x41, 0xb8, 0xbd, 0x9c, 0x0b, 0xa3, 0x6f, 0x14, 0x24, 0x19, 0x00, 0xb3, 0x11, 0x43, 0x8b, 0x16, 0x43, 0x00, 0x2e,
    0x67, 0x41, 0x46, 0x41, 0xf8, 0xbf, 0xbe, 0x0b, 0xb3, 0x11, 0x16, 0x43, 0x43, 0x8d, 0x00, 0x2e, 0xa5, 0x41, 0x86,
    0x41, 0xd8, 0xbe, 0x6e, 0x0b, 0xeb, 0x10, 0x03, 0x43, 0x13, 0x30, 0x27, 0x2e, 0x18, 0x00, 0x03, 0x31, 0x27, 0x2e,
    0xb8, 0xf0, 0xf6, 0x6f, 0xe7, 0x6f, 0xc4, 0x6f, 0xb5, 0x6f, 0xd3, 0x6f, 0xa0, 0x5f, 0xc8, 0x2e, 0xa0, 0x50, 0x80,
    0x7f, 0x91, 0x7f, 0xe7, 0x7f, 0xd5, 0x7f, 0xc4, 0x7f, 0xb3, 0x7f, 0xa2, 0x7f, 0xf6, 0x7f, 0x7b, 0x7f, 0x00, 0x2e,
    0x01, 0x2e, 0xb9, 0xf0, 0x60, 0x7f, 0x10, 0x30, 0x61, 0x6f, 0x08, 0x08, 0x00, 0xb2, 0x01, 0x2f, 0x98, 0x2e, 0x47,
    0xb1, 0x10, 0x30, 0x21, 0x2e, 0xb9, 0xf0, 0x21, 0x2e, 0x5f, 0xf0, 0xf6, 0x6f, 0x91, 0x6f, 0xa2, 0x6f, 0xb3, 0x6f,
    0xc4, 0x6f, 0xd5, 0x6f, 0xe7, 0x6f, 0x7b, 0x6f, 0x80, 0x6f, 0x60, 0x5f, 0xc8, 0x2e, 0x98, 0x2e, 0xe6, 0xb0, 0x20,
    0x26, 0x98, 0x2e, 0xe5, 0x00, 0x98, 0x2e, 0x98, 0x01, 0x98, 0x2e, 0xfc, 0x00, 0x98, 0x2e, 0xe9, 0x00, 0x01, 0x2e,
    0x40, 0xf0, 0x21, 0x2e, 0x24, 0x00, 0x10, 0x30, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0xa0, 0x01, 0x21, 0x30, 0x10,
    0x24, 0x19, 0x00, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x05, 0x2e, 0x18, 0x00, 0x80, 0xb2, 0x02, 0x30, 0x05, 0x2f,
    0x23, 0x2e, 0x5f, 0xf0, 0x25, 0x2e, 0x18, 0x00, 0x98, 0x2e, 0x00, 0xb0, 0x98, 0x2e, 0x8a, 0xb2, 0xec, 0x2d, 0x10,
    0x30, 0x21, 0x2e, 0xbb, 0xf0, 0xb8, 0x2e, 0x1a, 0x24, 0x26, 0x00, 0x80, 0x2e, 0x70, 0x01, 0x10, 0x50, 0x01, 0x2e,
    0x55, 0xf0, 0xf0, 0x7f, 0x00, 0x2e, 0xf0, 0x6f, 0x21, 0x2e, 0x55, 0xf0, 0xf0, 0x5f, 0xb8, 0x2e, 0x70, 0x50, 0xf4,
    0x7f, 0xe3, 0x7f, 0xd2, 0x7f, 0xc1, 0x7f, 0x12, 0x30, 0x03, 0x2e, 0x4e, 0x00, 0x91, 0x14, 0x92, 0x7f, 0x00, 0x31,
    0xc4, 0x6f, 0x95, 0x6f, 0xe3, 0x6f, 0xa5, 0x0f, 0x70, 0x84, 0x01, 0x04, 0x14, 0x2f, 0xd5, 0x6f, 0x00, 0xa9, 0x01,
    0x2f, 0xa5, 0x7f, 0x21, 0x2d, 0xdd, 0x04, 0xb3, 0x7f, 0x40, 0xb2, 0xb3, 0x6f, 0x1c, 0x18, 0x06, 0x2f, 0x50, 0xa0,
    0x01, 0x2f, 0xba, 0x11, 0x03, 0x2d, 0x71, 0x12, 0xb8, 0x14, 0x8a, 0x0b, 0x6e, 0x00, 0xa1, 0x7f, 0x11, 0x2d, 0xf7,
    0x6f, 0xfb, 0x05, 0xb7, 0x7f, 0x25, 0x05, 0xb5, 0x6f, 0x2c, 0x18, 0x40, 0xb2, 0x06, 0x2f, 0x50, 0xa0, 0x01, 0x2f,
    0xba, 0x11, 0x03, 0x2d, 0x71, 0x12, 0xb8, 0x14, 0x8a, 0x0b, 0x5e, 0x00, 0xa1, 0x7f, 0x00, 0x2e, 0xa0, 0x6f, 0x90,
    0x5f, 0xb8, 0x2e, 0x10, 0x24, 0x60, 0x00, 0x11, 0x24, 0x52, 0xf0, 0x12, 0x40, 0x52, 0x42, 0x28, 0xb5, 0x52, 0x42,
    0x00, 0x2e, 0x12, 0x40, 0x42, 0x42, 0x42, 0x82, 0x00, 0x40, 0x50, 0x42, 0x08, 0xb4, 0x40, 0x42, 0x7e, 0x80, 0xa8,
    0xb4, 0x01, 0x42, 0xb8, 0x2e, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0xb0, 0x50,
    0xf0, 0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x01, 0x01, 0x02, 0xbc, 0x0f, 0xb8, 0xe0, 0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x01,
    0x01, 0x01, 0xbc, 0x0f, 0xb8, 0xd0, 0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x01, 0x01, 0x0f, 0xb8, 0xc0, 0x7f, 0x02, 0x30,
    0xe6, 0x6f, 0xd4, 0x6f, 0xc3, 0x6f, 0x80, 0x91, 0x04, 0x2f, 0x00, 0x91, 0x02, 0x2f, 0xc0, 0xb2, 0x90, 0x2e, 0xe2,
    0xb0, 0xf0, 0x6f, 0x0b, 0x2e, 0x82, 0x00, 0x01, 0x82, 0x40, 0x91, 0x14, 0x2f, 0x41, 0x87, 0x27, 0x2e, 0x82, 0x00,
    0x00, 0x40, 0x21, 0x2e, 0x1f, 0x00, 0x53, 0x40, 0x10, 0x24, 0x20, 0x00, 0x13, 0x42, 0x00, 0x2e, 0x41, 0x40, 0x01,
    0x42, 0x25, 0x2e, 0x1c, 0x00, 0x25, 0x2e, 0x1d, 0x00, 0x25, 0x2e, 0x22, 0x00, 0x50, 0x5f, 0xb8, 0x2e, 0x0b, 0x2e,
    0x00, 0x01, 0xd5, 0xbe, 0xd5, 0xba, 0xb5, 0x7f, 0x00, 0x2e, 0x0b, 0x2e, 0x01, 0x01, 0xd3, 0xbe, 0xd3, 0xba, 0xa5,
    0x7f, 0x00, 0x2e, 0x0b, 0x2e, 0x00, 0x01, 0xd4, 0xbe, 0xdf, 0xba, 0x95, 0x7f, 0x00, 0x2e, 0x95, 0x6f, 0x0f, 0x2e,
    0x1e, 0x00, 0x3d, 0x1a, 0x05, 0x2f, 0x25, 0x2e, 0x1c, 0x00, 0x25, 0x2e, 0x1d, 0x00, 0x2b, 0x2e, 0x1e, 0x00, 0x82,
    0x7f, 0x72, 0x7f, 0x80, 0x91, 0x62, 0x7f, 0x01, 0x2f, 0x06, 0x30, 0x07, 0x2d, 0x06, 0x40, 0x0f, 0x2e, 0x1f, 0x00,
    0xb7, 0x05, 0x80, 0xa9, 0xd6, 0x05, 0xb7, 0x23, 0x86, 0x7f, 0x00, 0x91, 0x01, 0x2f, 0x04, 0x30, 0x07, 0x2d, 0x44,
    0x40, 0x0d, 0x2e, 0x20, 0x00, 0x26, 0x05, 0x00, 0xa9, 0x94, 0x05, 0x26, 0x23, 0x74, 0x7f, 0xc0, 0x90, 0x01, 0x2f,
    0x00, 0x2e, 0x09, 0x2d, 0x02, 0x86, 0x00, 0x2e, 0xc3, 0x40, 0x09, 0x2e, 0x21, 0x00, 0xdc, 0x04, 0xc0, 0xa8, 0x93,
    0x04, 0x9a, 0x22, 0x62, 0x7f, 0x12, 0x30, 0x84, 0x6f, 0xb3, 0x6f, 0x63, 0x0f, 0x14, 0x30, 0x08, 0x2f, 0x74, 0x6f,
    0x63, 0x0f, 0x14, 0x30, 0x04, 0x2f, 0x64, 0x6f, 0x63, 0x0f, 0x14, 0x30, 0x00, 0x2f, 0x04, 0x30, 0x54, 0x7f, 0x40,
    0x91, 0x0b, 0x2e, 0x1c, 0x00, 0x54, 0x6f, 0xa3, 0x6f, 0x6a, 0x29, 0x1d, 0x2f, 0x00, 0x91, 0x06, 0x30, 0x14, 0x24,
    0x20, 0x00, 0x0d, 0x2f, 0x2d, 0x2e, 0x1c, 0x00, 0x05, 0x2e, 0x1d, 0x00, 0x81, 0x84, 0x25, 0x2e, 0x1d, 0x00, 0x05,
    0x2e, 0x1d, 0x00, 0x53, 0x0e, 0x2b, 0x2f, 0x2d, 0x2e, 0x22, 0x00, 0x29, 0x2d, 0x2b, 0x2e, 0x1c, 0x00, 0x2d, 0x2e,
    0x1d, 0x00, 0x0b, 0x2e, 0x1c, 0x00, 0x6b, 0x0e, 0x20, 0x2f, 0x25, 0x2e, 0x22, 0x00, 0x1e, 0x2d, 0x00, 0xb3, 0x05,
    0x2f, 0x02, 0x30, 0x25, 0x2e, 0x1c, 0x00, 0x25, 0x2e, 0x22, 0x00, 0x08, 0x2d, 0x2b, 0x2e, 0x1c, 0x00, 0x09, 0x2e,
    0x1c, 0x00, 0x63, 0x0e, 0x01, 0x2f, 0x25, 0x2e, 0x22, 0x00, 0x02, 0x40, 0x25, 0x2e, 0x1f, 0x00, 0x31, 0x25, 0x00,
    0x2e, 0xd5, 0x40, 0x12, 0x24, 0x20, 0x00, 0x42, 0x25, 0x95, 0x42, 0x00, 0x2e, 0xc3, 0x40, 0x83, 0x42, 0x00, 0x2e,
    0x05, 0x2e, 0x22, 0x00, 0x80, 0xb2, 0x0d, 0x2f, 0x00, 0x40, 0x21, 0x2e, 0x1f, 0x00, 0x50, 0x40, 0x10, 0x43, 0x00,
    0x2e, 0x40, 0x40, 0x00, 0x43, 0x20, 0x30, 0x21, 0x2e, 0x5e, 0xf0, 0x02, 0x2d, 0x25, 0x2e, 0x82, 0x00, 0x50, 0x5f,
    0xb8, 0x2e, 0x20, 0x50, 0x00, 0x30, 0xe0, 0x7f, 0xfb, 0x7f, 0x11, 0x24, 0xb1, 0xf0, 0x42, 0x40, 0x43, 0x30, 0x93,
    0x0a, 0x42, 0x42, 0x58, 0x82, 0x12, 0x24, 0xaf, 0x00, 0x62, 0x42, 0x12, 0x24, 0xff, 0x00, 0x42, 0x42, 0x69, 0x82,
    0x72, 0x3c, 0x43, 0x40, 0x9a, 0x08, 0x83, 0x32, 0x93, 0x0a, 0x42, 0x42, 0x42, 0x82, 0x02, 0x3f, 0x43, 0x40, 0x9a,
    0x08, 0x52, 0x42, 0x0b, 0x31, 0x4b, 0x42, 0x7e, 0x82, 0x52, 0x31, 0x42, 0x42, 0x11, 0x24, 0xfe, 0x00, 0x05, 0x2e,
    0x40, 0xf0, 0x51, 0x08, 0x5e, 0x90, 0x27, 0x2f, 0x11, 0x24, 0x00, 0x02, 0x12, 0x24, 0x05, 0x80, 0x13, 0x24, 0xff,
    0xb7, 0x1b, 0x24, 0x00, 0xb0, 0x04, 0x30, 0x05, 0x30, 0x56, 0x32, 0x6e, 0x1a, 0x00, 0x2f, 0xa5, 0x34, 0x69, 0x1a,
    0x01, 0x2f, 0x5b, 0x25, 0x00, 0x2e, 0x56, 0x41, 0x26, 0x0d, 0x06, 0x30, 0xcf, 0xbb, 0x41, 0xbe, 0xc0, 0x91, 0x01,
    0x2f, 0x00, 0x2e, 0x01, 0x2d, 0x22, 0x0d, 0x81, 0x8d, 0x90, 0xa1, 0xf5, 0x2f, 0xeb, 0x0e, 0xe8, 0x2f, 0x01, 0x2e,
    0x25, 0x00, 0x20, 0x1a, 0x05, 0x2f, 0x20, 0x30, 0xe0, 0x7f, 0x03, 0x2d, 0x30, 0x30, 0xe0, 0x7f, 0x00, 0x2e, 0xe0,
    0x6f, 0x00, 0xb2, 0x06, 0x2f, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0xa0, 0x01, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e,
    0xfb, 0x6f, 0xe0, 0x5f, 0xb8, 0x2e, 0x40, 0x50, 0xfb, 0x7f, 0x98, 0x2e, 0x5c, 0xb2, 0x12, 0x24, 0x4f, 0x00, 0x90,
    0x42, 0x81, 0x42, 0xba, 0x82, 0xd1, 0x7f, 0xe2, 0x7f, 0x98, 0x2e, 0xa9, 0xb1, 0xd1, 0x6f, 0x00, 0x2e, 0x41, 0x40,
    0x40, 0xb2, 0x4c, 0x2f, 0xe1, 0x6f, 0x44, 0x86, 0x03, 0x2e, 0x4f, 0x00, 0xc2, 0x40, 0xf7, 0x86, 0x4a, 0x04, 0xc1,
    0x42, 0x00, 0x2e, 0xc2, 0x40, 0x80, 0xac, 0x01, 0x2f, 0x23, 0x2e, 0x4b, 0x00, 0xd1, 0x40, 0xd2, 0x40, 0x0a, 0x0f,
    0x01, 0x2f, 0x40, 0xac, 0x02, 0x2f, 0x01, 0x30, 0x23, 0x2e, 0x4b, 0x00, 0xfe, 0x82, 0xc2, 0x40, 0x43, 0x40, 0xd3,
    0x04, 0x46, 0x84, 0xc3, 0x7f, 0x85, 0x86, 0xc5, 0x82, 0x45, 0x80, 0x44, 0x40, 0xc1, 0x6f, 0xc3, 0x40, 0xe0, 0x7f,
    0xd1, 0x7f, 0x00, 0x2e, 0x82, 0x40, 0x98, 0x2e, 0xaa, 0x01, 0xe1, 0x6f, 0x72, 0x84, 0x40, 0x42, 0x85, 0x86, 0xc5,
    0x82, 0x45, 0x80, 0x44, 0x40, 0xc3, 0x40, 0xd1, 0x6f, 0xe0, 0x7f, 0x00, 0x2e, 0x82, 0x40, 0x98, 0x2e, 0xaa, 0x01,
    0xe1, 0x6f, 0x72, 0x84, 0x40, 0x42, 0x85, 0x86, 0xc5, 0x82, 0x45, 0x80, 0x44, 0x40, 0xc3, 0x40, 0xd1, 0x6f, 0xe0,
    0x7f, 0x00, 0x2e, 0x82, 0x40, 0x98, 0x2e, 0xaa, 0x01, 0xe1, 0x6f, 0x00, 0x2e, 0x40, 0x42, 0x98, 0x2e, 0xe6, 0x01,
    0x11, 0x30, 0x23, 0x2e, 0x5e, 0xf0, 0xfb, 0x6f, 0xc0, 0x5f, 0xb8, 0x2e, 0x01, 0x2e, 0x02, 0x01, 0x8e, 0xbc, 0x01,
    0x2e, 0x4a, 0x00, 0x9e, 0xb8, 0x01, 0x1a, 0x5f, 0x2f, 0x01, 0x2e, 0x02, 0x01, 0x0e, 0xbc, 0x0e, 0xb8, 0x21, 0x2e,
    0x4a, 0x00, 0x03, 0x2e, 0x4a, 0x00, 0x43, 0xb2, 0x10, 0x24, 0x4d, 0x00, 0x3c, 0x2f, 0x42, 0xb2, 0x22, 0x2f, 0x41,
    0xb2, 0x06, 0x2f, 0x01, 0x30, 0x11, 0x42, 0x01, 0x42, 0x3e, 0x80, 0x00, 0x2e, 0x01, 0x42, 0xb8, 0x2e, 0x03, 0x2e,
    0x24, 0x00, 0x5f, 0x90, 0x62, 0x30, 0x11, 0x24, 0x81, 0x00, 0x07, 0x2f, 0x30, 0x25, 0x34, 0x37, 0xd4, 0x42, 0xc2,
    0x42, 0xfe, 0x86, 0x00, 0x2e, 0xc1, 0x42, 0x00, 0x2e, 0x07, 0x2e, 0x24, 0x00, 0xde, 0x90, 0x35, 0x2f, 0x63, 0x36,
    0x13, 0x42, 0x02, 0x42, 0x3e, 0x80, 0x00, 0x2e, 0x01, 0x42, 0xb8, 0x2e, 0x03, 0x2e, 0x24, 0x00, 0x5f, 0xb2, 0x52,
    0x30, 0x21, 0x32, 0x0a, 0x2f, 0x07, 0x2e, 0x24, 0x00, 0xde, 0x90, 0x24, 0x2f, 0x23, 0x31, 0x13, 0x42, 0x02, 0x42,
    0x3e, 0x80, 0x00, 0x2e, 0x01, 0x42, 0xb8, 0x2e, 0x03, 0x32, 0x13, 0x42, 0x02, 0x42, 0x3e, 0x80, 0x00, 0x2e, 0x01,
    0x42, 0xb8, 0x2e, 0x03, 0x2e, 0x24, 0x00, 0x5f, 0xb2, 0x42, 0x30, 0x11, 0x31, 0x0a, 0x2f, 0x07, 0x2e, 0x24, 0x00,
    0xde, 0x90, 0x0c, 0x2f, 0xa3, 0x30, 0x13, 0x42, 0x02, 0x42, 0x3e, 0x80, 0x00, 0x2e, 0x01, 0x42, 0xb8, 0x2e, 0x63,
    0x31, 0x13, 0x42, 0x02, 0x42, 0x3e, 0x80, 0x00, 0x2e, 0x01, 0x42, 0xb8, 0x2e, 0x12, 0x24, 0x59, 0x00, 0x90, 0x40,
    0x84, 0x82, 0x20, 0x50, 0x50, 0x42, 0x77, 0x80, 0x82, 0x40, 0x42, 0x42, 0xfb, 0x7f, 0x05, 0x82, 0x00, 0x40, 0x40,
    0x42, 0x7c, 0x80, 0x05, 0x82, 0x00, 0x40, 0x40, 0x42, 0x7c, 0x80, 0x05, 0x82, 0x00, 0x40, 0x40, 0x42, 0x77, 0x84,
    0x00, 0x2e, 0x90, 0x40, 0x84, 0x82, 0x82, 0x40, 0x50, 0x42, 0x77, 0x80, 0x42, 0x42, 0x05, 0x82, 0x00, 0x40, 0x40,
    0x42, 0x7c, 0x80, 0x05, 0x82, 0x00, 0x40, 0x40, 0x42, 0x7c, 0x80, 0x05, 0x82, 0x00, 0x40, 0x40, 0x42, 0x7c, 0x82,
    0xe1, 0x7f, 0x98, 0x2e, 0x5c, 0xb2, 0xe2, 0x6f, 0x00, 0x2e, 0x90, 0x42, 0x81, 0x42, 0xbc, 0x82, 0x10, 0x24, 0x33,
    0xf0, 0x23, 0x40, 0x02, 0x40, 0xb8, 0xbd, 0x9a, 0x0a, 0x03, 0x80, 0x52, 0x42, 0x00, 0x2e, 0x23, 0x40, 0x02, 0x40,
    0xb8, 0xbd, 0x9a, 0x0a, 0x03, 0x80, 0x52, 0x42, 0x00, 0x2e, 0x22, 0x40, 0x00, 0x40, 0x28, 0xbd, 0x10, 0x0a, 0x40,
    0x42, 0x00, 0x2e, 0xfb, 0x6f, 0xe0, 0x5f, 0xb8, 0x2e, 0x11, 0x24, 0x28, 0xf0, 0x50, 0x50, 0x60, 0x40, 0xf0, 0x7f,
    0x51, 0x25, 0x60, 0x40, 0xe0, 0x7f, 0x00, 0x2e, 0x41, 0x40, 0xd1, 0x7f, 0x00, 0x2e, 0xe2, 0x6f, 0xd0, 0x6f, 0x00,
    0xb2, 0xf3, 0x6f, 0xa8, 0xb8, 0x28, 0xbe, 0x59, 0x0a, 0x20, 0x0a, 0x01, 0x2f, 0xb0, 0x5f, 0xb8, 0x2e, 0x45, 0x41,
    0xc5, 0x7f, 0x00, 0x2e, 0xc5, 0x6f, 0x40, 0x91, 0x09, 0x2f, 0x05, 0x2e, 0x28, 0xf0, 0xb2, 0x7f, 0x00, 0x2e, 0xb2,
    0x6f, 0x1a, 0x1a, 0x07, 0x2f, 0xf0, 0x3f, 0x13, 0x25, 0x05, 0x2d, 0x15, 0x1a, 0x02, 0x2f, 0x10, 0x24, 0xff, 0x00,
    0x20, 0x0a, 0xb0, 0x5f, 0xb8, 0x2e, 0x01, 0x2e, 0x03, 0x01, 0x8f, 0xbc, 0x01, 0x2e, 0x23, 0x00, 0x9f, 0xb8, 0x01,
    0x1a, 0x12, 0x2f, 0x01, 0x2e, 0x03, 0x01, 0x0f, 0xbc, 0x0f, 0xb8, 0x21, 0x2e, 0x23, 0x00, 0x11, 0x30, 0x05, 0x2e,
    0x23, 0x00, 0x51, 0x08, 0xd2, 0x3f, 0x01, 0x2e, 0x07, 0xf0, 0x02, 0x08, 0x91, 0xbc, 0x01, 0x0a, 0x21, 0x2e, 0x07,
    0xf0, 0xb8, 0x2e, 0xb8, 0x2e, 0x10, 0x50, 0x12, 0x24, 0x6e, 0x00, 0x00, 0x30, 0x1b, 0x2d, 0xf1, 0x6f, 0xd1, 0x00,
    0x00, 0x2e, 0xc0, 0x42, 0xbc, 0x84, 0xd1, 0x00, 0x00, 0x2e, 0xc0, 0x42, 0x8c, 0x84, 0xd1, 0x00, 0x00, 0x2e, 0xc0,
    0x42, 0xbc, 0x84, 0xd1, 0x00, 0x00, 0x2e, 0xc0, 0x42, 0x8c, 0x84, 0xd1, 0x00, 0x00, 0x2e, 0xc0, 0x42, 0xbc, 0x84,
    0xd1, 0x00, 0x00, 0x2e, 0xc0, 0x42, 0x41, 0x82, 0xf1, 0x7f, 0xb4, 0x84, 0xf1, 0x6f, 0x43, 0xa2, 0xe1, 0x2f, 0xf0,
    0x5f, 0xb8, 0x2e, 0xc0, 0x50, 0x92, 0x7f, 0xfb, 0x7f, 0x81, 0x7f, 0x00, 0x30, 0x60, 0x7f, 0x70, 0x7f, 0x50, 0x7f,
    0x00, 0x2e, 0x03, 0x2e, 0x04, 0x01, 0x9d, 0xbc, 0x9e, 0xb8, 0x41, 0x7f, 0x00, 0x2e, 0x42, 0x6f, 0x52, 0x7f, 0xe2,
    0x7f, 0x00, 0x2e, 0x83, 0x6f, 0xc4, 0x82, 0xd3, 0x7f, 0x0c, 0x2d, 0x55, 0x6f, 0x7f, 0x89, 0xdc, 0x01, 0x9d, 0x01,
    0xcb, 0x41, 0x8b, 0x43, 0xcc, 0x01, 0x4d, 0x01, 0xc7, 0x41, 0x47, 0x43, 0x54, 0x7f, 0x00, 0x2e, 0x54, 0x6f, 0x00,
    0xab, 0xf0, 0x2f, 0x9b, 0x6f, 0x8a, 0x00, 0x4b, 0x42, 0xc2, 0x7f, 0xb1, 0x7f, 0x50, 0x7f, 0x7c, 0x80, 0xa0, 0x7f,
    0x13, 0x24, 0x09, 0x01, 0x3f, 0x2d, 0x50, 0x6f, 0x18, 0x01, 0xc8, 0x84, 0xc8, 0x00, 0x50, 0x00, 0x05, 0x41, 0xc7,
    0x40, 0x44, 0x40, 0x61, 0x6f, 0x73, 0x6f, 0x2f, 0x18, 0x00, 0xb3, 0x0b, 0x2f, 0x10, 0xa1, 0x03, 0x2f, 0x30, 0x89,
    0xbc, 0x11, 0xce, 0x17, 0x06, 0x2d, 0x74, 0x13, 0x06, 0x31, 0xb4, 0x05, 0xbe, 0x15, 0xfc, 0x11, 0xae, 0x0b, 0x4e,
    0x00, 0xdf, 0x02, 0x61, 0x7f, 0x73, 0x7f, 0xb4, 0x84, 0x01, 0x82, 0xd1, 0x00, 0x88, 0x80, 0xa2, 0x6f, 0x11, 0x01,
    0x81, 0x00, 0xc3, 0x40, 0x05, 0x41, 0x84, 0x40, 0x1d, 0x18, 0x72, 0x6f, 0x00, 0xb3, 0x63, 0x6f, 0x0b, 0x2f, 0x10,
    0xa1, 0x03, 0x2f, 0x30, 0x89, 0xbc, 0x11, 0xce, 0x17, 0x06, 0x2d, 0x74, 0x13, 0x06, 0x31, 0xb4, 0x05, 0xbe, 0x15,
    0xfc, 0x11, 0xae, 0x0b, 0xde, 0x04, 0x97, 0x06, 0x63, 0x7f, 0x72, 0x7f, 0x51, 0x7f, 0x3c, 0x86, 0xb1, 0x6f, 0xe2,
    0x6f, 0x50, 0x6f, 0x42, 0x0e, 0xbc, 0x2f, 0xe0, 0x6f, 0xc8, 0x82, 0x98, 0x00, 0x48, 0x00, 0xc0, 0x6f, 0x83, 0x40,
    0x04, 0x40, 0x42, 0x40, 0x61, 0x6f, 0x70, 0x6f, 0x80, 0xb2, 0x1c, 0x18, 0x0b, 0x2f, 0x90, 0xa0, 0x03, 0x2f, 0xb0,
    0x84, 0xba, 0x11, 0xce, 0x17, 0x06, 0x2d, 0x03, 0x31, 0xda, 0x04, 0xfb, 0x14, 0x32, 0x13, 0xfa, 0x11, 0xa3, 0x0b,
    0x4e, 0x00, 0x07, 0x02, 0x61, 0x7f, 0x70, 0x7f, 0x00, 0x2e, 0x72, 0x6f, 0x80, 0xa8, 0x60, 0x6f, 0xd1, 0x6f, 0x13,
    0x2f, 0x80, 0x90, 0x03, 0x2f, 0x13, 0x24, 0xff, 0x7f, 0x43, 0x0f, 0x0d, 0x2f, 0xbf, 0xa0, 0x07, 0x2f, 0xbf, 0x90,
    0x03, 0x2f, 0x12, 0x24, 0x00, 0x80, 0x42, 0x0e, 0x01, 0x2f, 0x40, 0x42, 0x07, 0x2d, 0x10, 0x24, 0x00, 0x80, 0x40,
    0x42, 0x03, 0x2d, 0x10, 0x24, 0xff, 0x7f, 0x40, 0x42, 0x00, 0x2e, 0xfb, 0x6f, 0x40, 0x5f, 0x40, 0x40, 0xb8, 0x2e,
    0x11, 0x24, 0x63, 0x00, 0x30, 0x50, 0x10, 0x30, 0x50, 0x42, 0xfb, 0x7f, 0x10, 0x24, 0x33, 0xf0, 0x23, 0x40, 0x02,
    0x40, 0xb8, 0xbd, 0x9a, 0x0a, 0x03, 0x80, 0x52, 0x42, 0x00, 0x2e, 0x23, 0x40, 0x02, 0x40, 0xb8, 0xbd, 0x9a, 0x0a,
    0x03, 0x80, 0x52, 0x42, 0x00, 0x2e, 0x23, 0x40, 0x02, 0x40, 0xb8, 0xbd, 0x9a, 0x0a, 0x3c, 0x80, 0x42, 0x42, 0x7e,
    0x84, 0xe0, 0x7f, 0x86, 0x82, 0xd1, 0x7f, 0x00, 0x2e, 0x82, 0x40, 0x98, 0x2e, 0xcb, 0xb2, 0xd1, 0x6f, 0x7d, 0x82,
    0x00, 0x2e, 0x40, 0x42, 0x7e, 0x80, 0x0d, 0x82, 0x02, 0x40, 0xd1, 0x7f, 0x98, 0x2e, 0xcb, 0xb2, 0xd1, 0x6f, 0x76,
    0x82, 0x00, 0x2e, 0x40, 0x42, 0x7e, 0x80, 0x14, 0x82, 0x02, 0x40, 0xd1, 0x7f, 0x98, 0x2e, 0xcb, 0xb2, 0xd1, 0x6f,
    0x6f, 0x82, 0x00, 0x2e, 0x40, 0x42, 0x7e, 0x80, 0xe1, 0x6f, 0x12, 0x40, 0x52, 0x42, 0x28, 0xb5, 0x52, 0x42, 0x00,
    0x2e, 0x12, 0x40, 0x52, 0x42, 0x28, 0xb5, 0x52, 0x42, 0x00, 0x2e, 0x00, 0x40, 0x50, 0x42, 0x08, 0xb4, 0x40, 0x42,
    0x00, 0x2e, 0xfb, 0x6f, 0xd0, 0x5f, 0xb8, 0x2e, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
    0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
    0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
    0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
    0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

/****************************************************************************/

/*! Static Function Declarations
 ****************************************************************************/

/*!
 * @brief This API is used to validate the device structure pointer for
 * null conditions.
 *
 * @param[in] dev : Structure instance of bmi08x_dev.
 *
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error
 */
static int8_t null_ptr_check(const struct bmi08x_dev *dev);

/*!
 *  @brief This API reads the data from the given register address of accel sensor.
 *
 *  @param[in] reg_addr  : Register address from where the data to be read
 *  @param[out] reg_data : Pointer to data buffer to store the read data.
 *  @param[in] len       : No. of bytes of data to be read.
 *  @param[in] dev       : Structure instance of bmi08x_dev.
 *
 *  @return Result of API execution status
 *  @retval zero -> Success / -ve value -> Error
 */
static int8_t get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const struct bmi08x_dev *dev);

/*!
 *  @brief This API writes the given data to the register address
 *  of accel sensor.
 *
 *  @param[in] reg_addr  : Register address to where the data to be written.
 *  @param[in] reg_data  : Pointer to data buffer which is to be written
 *  in the sensor.
 *  @param[in] len       : No. of bytes of data to write.
 *  @param[in] dev       : Structure instance of bmi08x_dev.
 *
 *  @return Result of API execution status
 *  @retval zero -> Success / -ve value -> Error
 */
static int8_t set_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const struct bmi08x_dev *dev);

/*!
 * @brief This API configures the pins which fire the
 * interrupt signal when any interrupt occurs.
 *
 * @param[in] int_config  : Structure instance of bmi08x_accel_int_channel_cfg.
 * @param[in] dev         : Structure instance of bmi08x_dev.
 *
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error
 */
static int8_t set_int_pin_config(const struct bmi08x_accel_int_channel_cfg *int_config, const struct bmi08x_dev *dev);

/*!
 * @brief This API sets the data ready interrupt for accel sensor
 *
 * @param[in] int_config  : Structure instance of bmi08x_accel_int_channel_cfg.
 * @param[in] dev         : Structure instance of bmi08x_dev.
 *
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error
 */
static int8_t set_accel_data_ready_int(const struct bmi08x_accel_int_channel_cfg *int_config,
                                       const struct bmi08x_dev *dev);

/*!
 * @brief This API sets the synchronized data ready interrupt for accel sensor
 *
 * @param[in] int_config  : Structure instance of bmi08x_accel_int_channel_cfg.
 * @param[in] dev         : Structure instance of bmi08x_dev.
 *
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error
 */
static int8_t set_accel_sync_data_ready_int(const struct bmi08x_accel_int_channel_cfg *int_config,
                                            const struct bmi08x_dev *dev);

/*!
 * @brief This API configures the given interrupt channel as input for accel sensor
 *
 * @param[in] int_config  : Structure instance of bmi08x_accel_int_channel_cfg.
 * @param[in] dev         : Structure instance of bmi08x_dev.
 *
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error
 */
static int8_t set_accel_sync_input(const struct bmi08x_accel_int_channel_cfg *int_config, const struct bmi08x_dev *dev);

/*!
 * @brief This API sets the anymotion interrupt for accel sensor
 *
 * @param[in] int_config  : Structure instance of bmi08x_accel_int_channel_cfg.
 * @param[in] dev         : Structure instance of bmi08x_dev.
 *
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error
 */
static int8_t set_accel_anymotion_int(const struct bmi08x_accel_int_channel_cfg *int_config,
                                      const struct bmi08x_dev *dev);

/*!
 * @brief This API writes the config stream data in memory using burst mode
 *
 * @param[in] stream_data : Pointer to store data of 32 bytes
 * @param[in] index       : Represents value in multiple of 32 bytes
 * @param[in] dev         : Structure instance of bmi08x_dev.
 *
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error
 */
static int8_t stream_transfer_write(const uint8_t *stream_data, uint16_t index, const struct bmi08x_dev *dev);

/*!
 * @brief This API performs the pre-requisites needed to perform the self test
 *
 * @param[in] dev : structure instance of bmi08x_dev
 *
 * @return Result of API execution status
 * @retval zero -> Success  / -ve value -> Error
 */
static int8_t enable_self_test(struct bmi08x_dev *dev);

/*!
 * @brief This API reads the accel data with the positive excitation
 *
 * @param[out] accel_pos : Structure pointer to store accel data
 *                        for positive excitation
 * @param[in] dev   : structure instance of bmi08x_dev
 *
 * @return Result of API execution status
 * @retval zero -> Success  / -ve value -> Error
 */
static int8_t positive_excited_accel(struct bmi08x_sensor_data *accel_pos, const struct bmi08x_dev *dev);

/*!
 * @brief This API reads the accel data with the negative excitation
 *
 * @param[out] accel_neg : Structure pointer to store accel data
 *                        for negative excitation
 * @param[in] dev   : structure instance of bmi08x_dev
 *
 * @return Result of API execution status
 * @retval zero -> Success  / -ve value -> Error
 */
static int8_t negative_excited_accel(struct bmi08x_sensor_data *accel_neg, const struct bmi08x_dev *dev);

/*!
 * @brief This API validates the self test results
 *
 * @param[in] accel_pos : Structure pointer to store accel data
 *                        for positive excitation
 * @param[in] accel_neg : Structure pointer to store accel data
 *                        for negative excitation
 *
 * @return Result of API execution status
 * @retval zero -> Success / +ve value -> Self test fail
 */
static int8_t validate_accel_self_test(const struct bmi08x_sensor_data *accel_pos,
                                       const struct bmi08x_sensor_data *accel_neg);

/*!
 * @brief This API converts lsb value of axes to mg for self-test
 *
 * @param[in] accel_data_diff     : Pointer variable used to pass accel difference
 * values in g
 *
 * @param[out] accel_data_diff_mg : Pointer variable used to store accel
 * difference values in mg
 *
 * @return None
 */
static void convert_lsb_g(const struct selftest_delta_limit *accel_data_diff,
                          struct selftest_delta_limit *accel_data_diff_mg);

/*!
 * @brief This internal API is used to parse accelerometer data from the FIFO
 * data.
 *
 * @param[out] acc              : Structure instance of bmi08x_sensor_data
 *                                where the parsed data bytes are stored.
 * @param[in]  data_start_index : Index value of the accelerometer data bytes
 *                                which is to be parsed from the FIFO data.
 * @param[in]  fifo             : Structure instance of bmi08x_fifo_frame.
 *
 * @return None
 * @retval None
 */
static void unpack_accel_data(struct bmi08x_sensor_data *acc,
                              uint16_t data_start_index,
                              const struct bmi08x_fifo_frame *fifo);

/*!
 * @brief This internal API is used to parse the accelerometer data from the
 * FIFO data in both header and header-less mode. It updates the current data
 * byte to be parsed.
 *
 * @param[in,out] acc       : Structure instance of bmi08x_sensor_data where
 *                            where the parsed data bytes are stored.
 * @param[in,out] idx       : Index value of number of bytes parsed.
 * @param[in,out] acc_idx   : Index value of accelerometer data (x,y,z axes)
 *                            frame to be parsed.
 * @param[in]     frame     : Either data is enabled by user in header-less
 *                            mode or header frame value in header mode.
 * @param[in]     fifo      : Structure instance of bmi08x_fifo_frame.
 *
 * @return Result of API execution status
 *
 * @retval BMI08X_OK - Success.
 * @retval BMI08X_W_FIFO_EMPTY - Warning : FIFO is empty
 */
static int8_t unpack_accel_frame(struct bmi08x_sensor_data *acc,
                                 uint16_t *idx,
                                 uint16_t *acc_idx,
                                 uint16_t frame,
                                 const struct bmi08x_fifo_frame *fifo);

/*!
 * @brief This internal API is used to parse and store the skipped frame count
 * from the FIFO data.
 *
 * @param[in,out] data_index : Index of the FIFO data which contains skipped
 *                             frame count.
 * @param[in] fifo           : Structure instance of bmi08x_fifo_frame.
 *
 * @return Result of API execution status
 *
 * @retval BMI08X_OK - Success.
 * @retval BMI08X_W_FIFO_EMPTY - Warning : FIFO is empty
 * @retval BMI08X_W_PARTIAL_READ - Warning : There are more frames to be read
 */
static int8_t unpack_skipped_frame(uint16_t *data_index, struct bmi08x_fifo_frame *fifo);

/*!
 * @brief This internal API is used to move the data index ahead of the
 * current frame length parameter when unnecessary FIFO data appears while
 * extracting the user specified data.
 *
 * @param[in,out] data_index           : Index of the FIFO data which is to be
 *                                       moved ahead of the current frame length
 * @param[in]     current_frame_length : Number of bytes in the current frame.
 * @param[in]     fifo                 : Structure instance of bmi08x_fifo_frame.
 *
 * @return Result of API execution status
 *
 * @retval BMI08X_OK - Success.
 * @retval BMI08X_W_FIFO_EMPTY - Warning : FIFO is empty
 * @retval BMI08X_W_PARTIAL_READ - Warning : There are more frames to be read
 */
static int8_t move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bmi08x_fifo_frame *fifo);

/*!
 * @brief This internal API is used to parse and store the sensor time from the
 * FIFO data.
 *
 * @param[in,out] data_index : Index of the FIFO data which has the sensor time.
 * @param[in]     fifo       : Structure instance of bmi08x_fifo_frame.
 *
 * @return Result of API execution status
 *
 * @retval BMI08X_OK - Success.
 * @retval BMI08X_W_FIFO_EMPTY - Warning : FIFO is empty
 * @retval BMI08X_W_PARTIAL_READ - Warning : There are more frames to be read
 */
static int8_t unpack_sensortime_frame(uint16_t *data_index, struct bmi08x_fifo_frame *fifo);

/*!
 * @brief This internal API is used to reset the FIFO related configurations
 * in the FIFO frame structure for the next FIFO read.
 *
 * @param[in, out] fifo     : Structure instance of bmi08x_fifo_frame.
 * @param[in]      dev      : Structure instance of bmi08x_dev.
 *
 * @return None
 * @retval None
 */
static void reset_fifo_frame_structure(struct bmi08x_fifo_frame *fifo);

/*!
 * @brief This internal API is used to parse accelerometer data from the FIFO
 * data in header mode.
 *
 * @param[out] acc          : Structure instance of bmi08x_sens_data where
 *                            the parsed accelerometer data bytes are stored.
 * @param[in] accel_length  : Number of accelerometer frames (x,y,z data).
 * @param[in] fifo          : Structure instance of bmi08x_fifo_frame.
 * @param[in] dev           : Structure instance of bmi08x_dev.
 *
 * @return Result of API execution status
 *
 * @retval BMIX8X_OK - Success.
 * @retval BMI08X_W_FIFO_EMPTY - Warning : FIFO is empty
 * @retval BMI08X_W_PARTIAL_READ - Warning : There are more frames to be read
 */
static int8_t extract_acc_header_mode(struct bmi08x_sensor_data *acc,
                                      uint16_t *accel_length,
                                      struct bmi08x_fifo_frame *fifo,
                                      const struct bmi08x_dev *dev);

/*!
 * @brief This API sets the FIFO watermark interrupt for accel sensor
 *
 * @param[in] int_config  : Structure instance of bmi08x_accel_int_channel_cfg.
 * @param[in] dev         : Structure instance of bmi08x_dev.
 *
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error
 */
static int8_t set_fifo_wm_int(const struct bmi08x_accel_int_channel_cfg *int_config, const struct bmi08x_dev *dev);

/*!
 * @brief This API sets the FIFO full interrupt for accel sensor
 *
 * @param[in] int_config  : Structure instance of bmi08x_accel_int_channel_cfg.
 * @param[in] dev         : Structure instance of bmi08x_dev.
 *
 * @return Result of API execution status
 * @retval zero -> Success / -ve value -> Error
 */
static int8_t set_fifo_full_int(const struct bmi08x_accel_int_channel_cfg *int_config, const struct bmi08x_dev *dev);

/****************************************************************************/

/**\name        Extern Declarations
 ****************************************************************************/

/****************************************************************************/

/**\name        Globals
 ****************************************************************************/

/****************************************************************************/

/**\name        Function definitions
 ****************************************************************************/

/*!
 *  @brief This API is the entry point for accel sensor.
 *  It performs the selection of I2C/SPI read mechanism according to the
 *  selected interface and reads the chip-id of accel sensor.
 */
int8_t bmi08a_init(struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t chip_id = 0;

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if (rslt == BMI08X_OK)
    {
        if (dev->intf == BMI08X_SPI_INTF)
        {
            /* Set dummy byte in case of SPI interface */
            dev->dummy_byte = BMI08X_ENABLE;

            /* Dummy read of Chip-ID in SPI mode */
            rslt = get_regs(BMI08X_ACCEL_CHIP_ID_REG, &chip_id, 1, dev);
        }
        else
        {
            /* Make dummy byte 0 in case of I2C interface */
            dev->dummy_byte = BMI08X_DISABLE;
        }
        if (rslt == BMI08X_OK)
        {
            rslt = get_regs(BMI08X_ACCEL_CHIP_ID_REG, &chip_id, 1, dev);

            if (rslt == BMI08X_OK)
            {
                /* Check for chip id validity */
                if (chip_id == BMI08X_ACCEL_CHIP_ID)
                {
                    /* Store the chip ID in dev structure */
                    dev->accel_chip_id = chip_id;
                }
                else
                {
                    rslt = BMI08X_E_DEV_NOT_FOUND;
                }
            }
        }
    }

    return rslt;
}

/*!
 *  @brief This API is used to write the binary configuration in the sensor.
 */
int8_t bmi08a_write_config_file(const struct bmi08x_dev *dev)
{
    int8_t rslt;

    /* Config loading disable*/
    uint8_t config_load = BMI08X_DISABLE;
    uint8_t current_acc_pwr_ctrl = 0;
    uint16_t index = 0;
    uint8_t reg_data = 0;

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);

    /* Check if config file pointer is not null */
    if ((rslt == BMI08X_OK) && (dev->config_file_ptr != NULL))
    {

        /* Check whether the read/write length is valid */
        if (dev->read_write_len > 0)
        {
            /* deactivate accel, otherwise post processing can not be enabled safely */
            rslt = get_regs(BMI08X_ACCEL_PWR_CTRL_REG, &current_acc_pwr_ctrl, 1, dev);
            if (rslt != BMI08X_OK)
            {
                return rslt;
            }

            rslt = set_regs(BMI08X_ACCEL_PWR_CTRL_REG, &config_load, 1, dev);
            if (rslt == BMI08X_OK)
            {
                /*delay required to switch power modes*/
                dev->delay_ms(BMI08X_POWER_CONFIG_DELAY);
            }
            else
            {
                return rslt;
            }

            /* Disable config loading*/
            rslt = set_regs(BMI08X_ACCEL_INIT_CTRL_REG, &config_load, 1, dev);

            if (rslt == BMI08X_OK)
            {
                for (index = 0; index < BMI08X_CONFIG_STREAM_SIZE;
                     index += dev->read_write_len)
                {
                    /* Write the config stream */
                    rslt = stream_transfer_write((dev->config_file_ptr + index), index, dev);
                }
                if (rslt == BMI08X_OK)
                {
                    /* Enable config loading and FIFO mode */
                    config_load = BMI08X_ENABLE;

                    rslt = set_regs(BMI08X_ACCEL_INIT_CTRL_REG, &config_load, 1, dev);

                    if (rslt == BMI08X_OK)
                    {
                        /* Wait till ASIC is initialized. Refer the data-sheet
                         * for more information */
                        dev->delay_ms(BMI08X_ASIC_INIT_TIME_MS);

                        /* Check for config initialization status (1 = OK)*/
                        rslt = get_regs(BMI08X_ACCEL_INTERNAL_STAT_REG, &reg_data, 1, dev);
                    }
                    if (rslt == BMI08X_OK && reg_data != 1)
                    {
                        rslt = BMI08X_E_CONFIG_STREAM_ERROR;
                    }
                    else
                    {
                        /* reactivate accel */
                        rslt = set_regs(BMI08X_ACCEL_PWR_CTRL_REG, &current_acc_pwr_ctrl, 1, dev);
                        if (rslt == BMI08X_OK)
                        {
                            /*delay required to switch power modes*/
                            dev->delay_ms(BMI08X_POWER_CONFIG_DELAY);
                        }
                    }
                }
            }
        }
        else
        {
            rslt = BMI08X_E_RD_WR_LENGTH_INVALID;
        }
    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}

/*!
 *  @brief This API writes the feature configuration to the accel sensor.
 */
int8_t bmi08a_write_feature_config(uint8_t reg_addr, const uint16_t *reg_data, uint8_t len,
                                   const struct bmi08x_dev *dev)
{

    int8_t rslt;
    uint16_t read_length = (reg_addr * 2) + (len * 2);
    uint8_t feature_data[read_length];

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);
    if (rslt == BMI08X_OK)
    {
        /* Read feature space up to the given feature position */
        rslt = bmi08a_get_regs(BMI08X_ACCEL_FEATURE_CFG_REG, &feature_data[0], read_length, dev);

        if (rslt == BMI08X_OK)
        {
            /* Apply the given feature config. */
            for (int i = 0; i < len; ++i)
            {
                /* Be careful: the feature config space is 16bit aligned! */
                feature_data[(reg_addr * 2) + (i * 2)] = reg_data[i] & 0xFF;
                feature_data[(reg_addr * 2) + (i * 2) + 1] = reg_data[i] >> 8;
            }

            /* Write back updated feature space */
            rslt = bmi08a_set_regs(BMI08X_ACCEL_FEATURE_CFG_REG, &feature_data[0], read_length, dev);
        }
    }

    return rslt;
}

/*!
 *  @brief This API reads the data from the given register address of accel sensor.
 */
int8_t bmi08a_get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const struct bmi08x_dev *dev)
{
    int8_t rslt;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if ((rslt == BMI08X_OK) && (reg_data != NULL))
    {
        if (len > 0)
        {
            /* Reading from the register */
            rslt = get_regs(reg_addr, reg_data, len, dev);
        }
        else
        {
            rslt = BMI08X_E_RD_WR_LENGTH_INVALID;
        }
    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}

/*!
 *  @brief This API writes the given data to the register address
 *  of accel sensor.
 */
int8_t bmi08a_set_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const struct bmi08x_dev *dev)
{
    int8_t rslt;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if ((rslt == BMI08X_OK) && (reg_data != NULL))
    {
        if (len > 0)
        {
            /* Writing to the register */
            rslt = set_regs(reg_addr, reg_data, len, dev);
        }
        else
        {
            rslt = BMI08X_E_RD_WR_LENGTH_INVALID;
        }
    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}

/*!
 *  @brief This API reads the error status from the accel sensor.
 */
int8_t bmi08a_get_error_status(struct bmi08x_err_reg *err_reg, const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data = 0;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if (rslt == BMI08X_OK)
    {
        if (err_reg != NULL)
        {
            /* Read the error codes */
            rslt = get_regs(BMI08X_ACCEL_ERR_REG, &data, 1, dev);

            if (rslt == BMI08X_OK)
            {
                /* Fatal error */
                err_reg->fatal_err = BMI08X_GET_BITS_POS_0(data, BMI08X_FATAL_ERR);

                /* User error */
                err_reg->err_code = BMI08X_GET_BITS(data, BMI08X_ERR_CODE);
            }
        }
        else
        {
            rslt = BMI08X_E_NULL_PTR;
        }
    }

    return rslt;
}

/*!
 *  @brief This API reads the status of the accel sensor.
 */
int8_t bmi08a_get_status(uint8_t *status, const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data = 0;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if ((rslt == BMI08X_OK) && (status != NULL))
    {
        /* Read the status */
        rslt = get_regs(BMI08X_ACCEL_STATUS_REG, &data, 1, dev);

        if (rslt == BMI08X_OK)
        {
            /* Updating the status */
            *status = BMI08X_GET_BITS(data, BMI08X_ACCEL_STATUS);
        }
    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}

/*!
 *  @brief This API resets the accel sensor.
 */
int8_t bmi08a_soft_reset(const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if (rslt == BMI08X_OK)
    {
        data = BMI08X_SOFT_RESET_CMD;

        /* Reset accel device */
        rslt = set_regs(BMI08X_ACCEL_SOFTRESET_REG, &data, 1, dev);

        if (rslt == BMI08X_OK)
        {
            /* Delay 1 ms after reset value is written to its register */
            dev->delay_ms(BMI08X_ACCEL_SOFTRESET_DELAY_MS);

            /* After soft reset SPI mode in the initialization phase, need to  perform a dummy SPI read
             * operation, The soft-reset performs a fundamental reset to the device, which is largely
             * equivalent to a power cycle. */
            if (dev->intf == BMI08X_SPI_INTF)
            {
                /* Dummy SPI read operation of Chip-ID */
                rslt = get_regs(BMI08X_ACCEL_CHIP_ID_REG, &data, 1, dev);
            }
        }
    }

    return rslt;
}

/*!
 * @brief This API reads the accel config value i.e. odr, band width and range from the sensor,
 * store it in the bmi08x_dev structure instance passed by the user.
 *
 */
int8_t bmi08a_get_meas_conf(struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data[2];

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if (rslt == BMI08X_OK)
    {
        rslt = get_regs(BMI08X_ACCEL_CONF_REG, data, 2, dev);

        if (rslt == BMI08X_OK)
        {
            dev->accel_cfg.odr = data[0] & BMI08X_ACCEL_ODR_MASK;
            dev->accel_cfg.bw = (data[0] & BMI08X_ACCEL_BW_MASK) >> 4;
            dev->accel_cfg.range = data[1] & BMI08X_ACCEL_RANGE_MASK;
        }
    }

    return rslt;
}

/*!
 * @brief This API sets the output data rate, range and bandwidth
 * of accel sensor.
 */
int8_t bmi08a_set_meas_conf(const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data[2] = { 0 };
    uint8_t bw, range, odr;
    uint8_t is_odr_invalid = FALSE, is_bw_invalid = FALSE, is_range_invalid = FALSE;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if (rslt == BMI08X_OK)
    {
        odr = dev->accel_cfg.odr;
        bw = dev->accel_cfg.bw;
        range = dev->accel_cfg.range;

        /* Check for valid ODR */
        if ((odr < BMI08X_ACCEL_ODR_12_5_HZ) || (odr > BMI08X_ACCEL_ODR_1600_HZ))
        {
            /* Updating the status */
            is_odr_invalid = TRUE;
        }

        /* Check for valid bandwidth */
        if (bw > BMI08X_ACCEL_BW_NORMAL)
        {
            /* Updating the status */
            is_bw_invalid = TRUE;
        }
#if BMI08X_FEATURE_BMI085 == 1

        /* Check for valid Range */
        if (range > BMI085_ACCEL_RANGE_16G)
        {
            /* Updating the status */
            is_range_invalid = TRUE;
        }
#elif BMI08X_FEATURE_BMI088 == 1

        /* Check for valid Range */
        if (range > BMI088_ACCEL_RANGE_24G)
        {
            /* Updating the status */
            is_range_invalid = TRUE;
        }
#endif

        /* If ODR, BW and Range are valid, write it to accel config. registers */
        if ((!is_odr_invalid) && (!is_bw_invalid) && (!is_range_invalid))
        {
            /* Read accel config. register */
            rslt = get_regs(BMI08X_ACCEL_CONF_REG, data, 2, dev);
            if (rslt == BMI08X_OK)
            {
                /* Update data with new odr and bw values */
                data[0] = BMI08X_SET_BITS_POS_0(data[0], BMI08X_ACCEL_ODR, odr);
                data[0] = BMI08X_SET_BITS(data[0], BMI08X_ACCEL_BW, bw);

                /* Update data with current range values */
                data[1] = BMI08X_SET_BITS_POS_0(data[1], BMI08X_ACCEL_RANGE, range);

                /* write to range register */
                rslt = set_regs(BMI08X_ACCEL_CONF_REG, data, 2, dev);
            }
        }
        else
        {
            /* Invalid configuration present in ODR, BW, Range */
            rslt = BMI08X_E_INVALID_CONFIG;
        }
    }

    return rslt;
}

/*!
 * @brief This API reads the accel power mode from the sensor, store it in the bmi08x_dev structure
 * instance passed by the user.
 */
int8_t bmi08a_get_power_mode(struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if (rslt == BMI08X_OK)
    {
        rslt = get_regs(BMI08X_ACCEL_PWR_CONF_REG, &data, 1, dev);

        if (rslt == BMI08X_OK)
        {
            /* Updating the current power mode */
            dev->accel_cfg.power = data;
        }
    }

    return rslt;
}

/*!
 * @brief This API sets the power mode of the accel sensor.
 */
int8_t bmi08a_set_power_mode(const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t power_mode;
    uint8_t data[2];

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if (rslt == BMI08X_OK)
    {
        power_mode = dev->accel_cfg.power;

        /* Configure data array to write to accel power configuration register */
        if (power_mode == BMI08X_ACCEL_PM_ACTIVE)
        {
            data[0] = BMI08X_ACCEL_PM_ACTIVE;
            data[1] = BMI08X_ACCEL_POWER_ENABLE;
        }
        else if (power_mode == BMI08X_ACCEL_PM_SUSPEND)
        {
            data[0] = BMI08X_ACCEL_PM_SUSPEND;
            data[1] = BMI08X_ACCEL_POWER_DISABLE;
        }
        else
        {
            /* Invalid power input */
            rslt = BMI08X_E_INVALID_INPUT;
        }

        if (rslt == BMI08X_OK)
        {
            /*enable accel sensor*/
            rslt = set_regs(BMI08X_ACCEL_PWR_CONF_REG, &data[0], 1, dev);

            if (rslt == BMI08X_OK)
            {
                /*delay between power ctrl and power config*/
                dev->delay_ms(BMI08X_POWER_CONFIG_DELAY);

                /* write to accel power configuration register */
                rslt = set_regs(BMI08X_ACCEL_PWR_CTRL_REG, &data[1], 1, dev);

                if (rslt == BMI08X_OK)
                {
                    /*delay required to switch power modes*/
                    dev->delay_ms(BMI08X_POWER_CONFIG_DELAY);
                }
            }

        }
    }

    return rslt;
}

/*!
 * @brief This API reads the accel data from the sensor,
 * store it in the bmi08x_sensor_data structure instance
 * passed by the user.
 */
int8_t bmi08a_get_data(struct bmi08x_sensor_data *accel, const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data[6];
    uint8_t lsb, msb;
    uint16_t msblsb;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if ((rslt == BMI08X_OK) && (accel != NULL))
    {
        /* Read accel sensor data */
        rslt = get_regs(BMI08X_ACCEL_X_LSB_REG, data, 6, dev);

        if (rslt == BMI08X_OK)
        {
            lsb = data[0];
            msb = data[1];
            msblsb = (msb << 8) | lsb;
            accel->x = ((int16_t) msblsb); /* Data in X axis */

            lsb = data[2];
            msb = data[3];
            msblsb = (msb << 8) | lsb;
            accel->y = ((int16_t) msblsb); /* Data in Y axis */

            lsb = data[4];
            msb = data[5];
            msblsb = (msb << 8) | lsb;
            accel->z = ((int16_t) msblsb); /* Data in Z axis */
        }

    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}

/*!
 * @brief This API configures the necessary accel interrupt
 * based on the user settings in the bmi08x_int_cfg
 * structure instance.
 */
int8_t bmi08a_set_int_config(const struct bmi08x_accel_int_channel_cfg *int_config, const struct bmi08x_dev *dev)
{
    int8_t rslt;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if ((rslt == BMI08X_OK) && (int_config != NULL))
    {
        switch (int_config->int_type)
        {
            case BMI08X_ACCEL_DATA_RDY_INT:

                /* Data ready interrupt */
                rslt = set_accel_data_ready_int(int_config, dev);
                break;
            case BMI08X_ACCEL_SYNC_DATA_RDY_INT:

                /* synchronized data ready interrupt */
                rslt = set_accel_sync_data_ready_int(int_config, dev);
                break;
            case BMI08X_ACCEL_SYNC_INPUT:

                /* input for synchronization on accel */
                rslt = set_accel_sync_input(int_config, dev);
                break;
            case BMI08X_ACCEL_ANYMOTION_INT:

                /* Anymotion interrupt */
                rslt = set_accel_anymotion_int(int_config, dev);
                break;
            case BMI08X_FIFO_WM_INT:

                /* FIFO watermark interrupt */
                rslt = set_fifo_wm_int(int_config, dev);
                break;
            case BMI08X_FIFO_FULL_INT:

                /* FIFO full interrupt */
                rslt = set_fifo_full_int(int_config, dev);
                break;
            default:
                rslt = BMI08X_E_INVALID_CONFIG;
                break;
        }
    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}

/*!
 * @brief This API reads the temperature of the sensor in degree Celcius.
 */
#if ORIGIN_TEMP_API
int8_t bmi08a_get_sensor_temperature(const struct bmi08x_dev *dev, int32_t *sensor_temp)
{
    int8_t rslt;
    uint8_t data[2] = { 0 };
    uint16_t msb, lsb;
    uint16_t msblsb;
    int16_t temp;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if ((rslt == BMI08X_OK) && (sensor_temp != NULL))
    {
        /* Read sensor temperature */
        rslt = get_regs(BMI08X_TEMP_MSB_REG, data, 2, dev);

        if (rslt == BMI08X_OK)
        {
            msb = (data[0] << 3); /* MSB data */
            lsb = (data[1] >> 5); /* LSB data */
            msblsb = (uint16_t) (msb + lsb);

            if (msblsb > 1023)
            {
                /* Updating the msblsb */
                temp = (int16_t) (msblsb - 2048);
            }
            else
            {
                temp = (int16_t) msblsb;
            }

            /* sensor temperature */
            *sensor_temp = (temp * 125) + 23000;
        }

    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;

}
#endif
int8_t bmi08a_get_sensor_temperature(const struct bmi08x_dev *dev, int *sensor_temp)
{
    int8_t rslt;
    uint8_t data[2] = { 0 };
    uint16_t msb, lsb;
    uint16_t msblsb;
    int16_t temp;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if ((rslt == BMI08X_OK) && (sensor_temp != NULL))
    {
        /* Read sensor temperature */
        rslt = get_regs(BMI08X_TEMP_MSB_REG, data, 2, dev);

        if (rslt == BMI08X_OK)
        {
            msb = (data[0] << 3); /* MSB data */
            lsb = (data[1] >> 5); /* LSB data */
            msblsb = (uint16_t) (msb + lsb);

            if (msblsb > 1023)
            {
                /* Updating the msblsb */
                temp = (int16_t) (msblsb - 2048);
            }
            else
            {
                temp = (int16_t) msblsb;
            }

            /* sensor temperature */
            *sensor_temp = ((temp * 0.125) + 23)*100;
        }

    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;

}

///*!
// *  @brief This API reads the sensor time of the accel sensor.
// */
/*!
 *  @brief This API reads the sensor time of the accel sensor.
 */
 #if US_SENSORTIME==0
int8_t bmi08a_get_sensor_time(const struct bmi08x_dev *dev, uint32_t *sensor_time)
{
    int8_t rslt;
    uint8_t data[3] = { 0 };
    uint32_t byte2, byte1, byte0;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if ((rslt == BMI08X_OK) && (sensor_time != NULL))
    {
        /* Read 3-byte sensor time */
        rslt = get_regs(BMI08X_ACCEL_SENSORTIME_0_REG, data, 3, dev);

        if (rslt == BMI08X_OK)
        {
            byte0 = data[0]; /* Lower byte */
            byte1 = (data[1] << 8); /* Middle byte */
            byte2 = (data[2] << 16); /* Higher byte */

            /* Sensor time */
            *sensor_time = (byte2 | byte1 | byte0)*39.0625;
        }

    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}
#elif US_SENSORTIME==1
//int8_t bmi08a_get_sensor_time(const struct bmi08x_dev *dev, uint32_t *sensor_time)
//{
//    int8_t rslt;
//    uint8_t data[3] = { 0 };
//    uint32_t byte2, byte1, byte0;

//    /* Check for null pointer in the device structure*/
//    rslt = null_ptr_check(dev);

//    /* Proceed if null check is fine */
//    if ((rslt == BMI08X_OK) && (sensor_time != NULL))
//    {
//        /* Read 3-byte sensor time */
//        rslt = get_regs(BMI08X_ACCEL_SENSORTIME_0_REG, data, 3, dev);

//        if (rslt == BMI08X_OK)
//        {
//            byte0 = data[0]; /* Lower byte */
//            byte1 = (data[1] << 8); /* Middle byte */
//            byte2 = (data[2] << 16); /* Higher byte */

//            /* Sensor time */
//            *sensor_time = (byte2 | byte1 | byte0);
//        }

//    }
//    else
//    {
//        rslt = BMI08X_E_NULL_PTR;
//    }

//    return rslt;
//}

#endif

/*!
 *  @brief This API checks whether the self test functionality of the sensor
 *  is working or not.
 */
int8_t bmi08a_perform_selftest(struct bmi08x_dev *dev)
{
    int8_t rslt;
    int8_t self_test_rslt = 0;
    struct bmi08x_sensor_data accel_pos, accel_neg;

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);

    /* Proceed if null check is fine */
    if (rslt == BMI08X_OK)
    {
        /* pre-requisites for self test */
        rslt = enable_self_test(dev);

        if (rslt == BMI08X_OK)
        {
            rslt = positive_excited_accel(&accel_pos, dev);

            if (rslt == BMI08X_OK)
            {
                rslt = negative_excited_accel(&accel_neg, dev);

                if (rslt == BMI08X_OK)
                {
                    /* Validate the self test result */
                    rslt = validate_accel_self_test(&accel_pos, &accel_neg);

                    /* Store the status of self test result */
                    self_test_rslt = rslt;

                    /* Perform soft reset */
                    rslt = bmi08a_soft_reset(dev);

                    /* Check to ensure bus operations are success */
                    if (rslt == BMI08X_OK)
                    {
                        /* Restore self_test_rslt as return value */
                        rslt = self_test_rslt;
                    }
                }
            }
        }
    }

    return rslt;
}

/*!
 * @brief This API sets the FIFO configuration in the sensor.
 */
int8_t bmi08a_set_fifo_config(const struct accel_fifo_config *config, const struct bmi08x_dev *dev)
{
    /* Variable to define error */
    int8_t rslt;

    /* Array to store the default value of FIFO configuration
     * reserved registers
     */
    uint8_t data_array[2] = { 0 };

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);

    if (rslt == BMI08X_OK)
    {
        /* Get the FIFO configurations from the FIFO configure_1 and configure_2 register */
        rslt = bmi08a_get_regs(BMI08X_FIFO_CONFIG_0_ADDR, data_array, 2, dev);
        if (rslt == BMI08X_OK)
        {
            /* To set the stream mode or FIFO mode */
            data_array[0] = BMI08X_SET_BITS_POS_0(data_array[0], BMI08X_ACC_FIFO_MODE_CONFIG, config->mode);

            /* To enable the Accel in FIFO configuration */
            data_array[1] = BMI08X_SET_BITS(data_array[1], BMI08X_ACCEL_EN, config->accel_en);

            /* To enable the interrupt_1 in FIFO configuration */
            data_array[1] = BMI08X_SET_BITS(data_array[1], BMI08X_ACCEL_INT1_EN, config->int1_en);

            /* To enable the interrupt_2 in FIFO configuration */
            data_array[1] = BMI08X_SET_BITS(data_array[1], BMI08X_ACCEL_INT2_EN, config->int2_en);

            rslt = bmi08a_set_regs(BMI08X_FIFO_CONFIG_0_ADDR, data_array, 2, dev);
        }
    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}

/*!
 * @brief This API reads the FIFO configuration from the sensor.
 */
int8_t bmi08a_get_fifo_config(struct accel_fifo_config *config, const struct bmi08x_dev *dev)
{
    /* Variable to define error */
    int8_t rslt;

    /* Array to store data */
    uint8_t data[2] = { 0 };

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);
    if ((rslt == BMI08X_OK) && (config != NULL))
    {
        /* Get the FIFO configuration value */
        rslt = bmi08a_get_regs(BMI08X_FIFO_CONFIG_0_ADDR, data, BMI08X_FIFO_CONFIG_LENGTH, dev);
        if (rslt == BMI08X_OK)
        {
            /* Get mode selection */
            config->mode = BMI08X_GET_BITS_POS_0(data[0], BMI08X_ACC_FIFO_MODE_CONFIG);

            /* Get the accel enable */
            config->accel_en = BMI08X_GET_BITS(data[1], BMI08X_ACCEL_EN);

            /* Get the interrupt_1 enable/disable */
            config->int1_en = BMI08X_GET_BITS(data[1], BMI08X_ACCEL_INT1_EN);

            /* Get the interrupt_2 enable/disable */
            config->int2_en = BMI08X_GET_BITS(data[1], BMI08X_ACCEL_INT2_EN);
        }
    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}

/*!
 * @brief This API reads the FIFO data.
 */
int8_t bmi08a_read_fifo_data(struct bmi08x_fifo_frame *fifo, const struct bmi08x_dev *dev)
{
    /* Variable to define error */
    int8_t rslt;

    /* Array to store FIFO configuration data */
    uint8_t config_data = 0;

    /* Variable to define FIFO address */
    uint8_t addr = BMI08X_FIFO_DATA_ADDR;

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);
    if ((rslt == BMI08X_OK) && (fifo != NULL))
    {
        /* Clear the FIFO data structure */
        reset_fifo_frame_structure(fifo);

        /* Read FIFO data */
        rslt = bmi08a_get_regs(addr, fifo->data, fifo->length, dev);
        if (rslt == BMI08X_OK)
        {
            /* Get the set FIFO frame configurations */
            rslt = bmi08a_get_regs(BMI08X_FIFO_CONFIG_1_ADDR, &config_data, 1, dev);
            if (rslt == BMI08X_OK)
            {
                /* Get sensor enable status, of which the data
                 * is to be read
                 */
                fifo->data_enable = (uint16_t)((uint16_t)config_data & BMI08X_ACCEL_EN_MASK);
            }
        }
        else
        {
            rslt = BMI08X_E_COM_FAIL;
        }
    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}

/*!
 * @brief This API gets the length of FIFO data available in the sensor in
 * bytes.
 */
int8_t bmi08a_get_fifo_length(uint16_t *fifo_length, const struct bmi08x_dev *dev)
{
    /* Variable to define error */
    int8_t rslt;

    /* Array to store FIFO data length */
    uint8_t data[BMI08X_FIFO_DATA_LENGTH] = { 0 };

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);
    if ((rslt == BMI08X_OK) && (fifo_length != NULL))
    {
        /* read fifo length */
        rslt = bmi08a_get_regs(BMI08X_FIFO_LENGTH_0_ADDR, data, BMI08X_FIFO_DATA_LENGTH, dev);
        if (rslt == BMI08X_OK)
        {
            /* Get the MSB byte of FIFO length */
            data[1] = BMI08X_GET_BITS_POS_0(data[1], BMI08X_FIFO_BYTE_COUNTER_MSB);

            /* Get total FIFO length */
            (*fifo_length) = (uint16_t)((uint16_t)(data[1] << 8) | data[0]);
        }
        else
        {
            rslt = BMI08X_E_NULL_PTR;
        }
    }

    return rslt;
}

/*!
 * @brief This API sets the FIFO water-mark level in the sensor.
 */
int8_t bmi08a_get_fifo_wm(uint16_t *wm, const struct bmi08x_dev *dev)
{
    int8_t rslt;

    uint8_t data[2] = { 0 };

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);
    if (rslt == BMI08X_OK)
    {
        rslt = bmi08a_get_regs(BMI08X_FIFO_WTM_0_ADDR, data, BMI08X_FIFO_WTM_LENGTH, dev);
        if ((rslt == BMI08X_OK) && (wm != NULL))
        {
            *wm = (data[1] << 8) | (data[0]);
        }
        else
        {
            rslt = BMI08X_E_NULL_PTR;
        }
    }

    return rslt;
}

/*!
 * @brief This API sets the FIFO water-mark level in the sensor.
 */
int8_t bmi08a_set_fifo_wm(uint16_t wm, const struct bmi08x_dev *dev)
{
    /* Variable to define error */
    int8_t rslt;

    /* Array to store data */
    uint8_t data[2] = { 0 };

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);
    if (rslt == BMI08X_OK)
    {
        /* Get LSB value of FIFO water-mark */
        data[0] = BMI08X_GET_LSB(wm);

        /* Get MSB value of FIFO water-mark */
        data[1] = BMI08X_GET_MSB(wm);

        /* Set the FIFO water-mark level */
        rslt = bmi08a_set_regs(BMI08X_FIFO_WTM_0_ADDR, data, BMI08X_FIFO_WTM_LENGTH, dev);
    }

    return rslt;
}

/*!
 * @brief This API parses and extracts the accelerometer frames from FIFO data
 * read by the "bmi08x_read_fifo_data" API and stores it in the "accel_data"
 * structure instance.
 */
int8_t bmi08a_extract_accel(struct bmi08x_sensor_data *accel_data,
                            uint16_t *accel_length,
                            struct bmi08x_fifo_frame *fifo,
                            const struct bmi08x_dev *dev)
{
    /* Variable to define error */
    int8_t rslt;

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);
    if ((rslt == BMI08X_OK) && (accel_data != NULL) && (accel_length != NULL) && (fifo != NULL))
    {
        /* Parsing the FIFO data in header mode */
        rslt = extract_acc_header_mode(accel_data, accel_length, fifo, dev);

    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}

/*!
 * @brief This API reads the down sampling rates which is configured for
 * accelerometer FIFO data.
 */
int8_t bmi08a_get_fifo_down_sample(uint8_t *fifo_downs, const struct bmi08x_dev *dev)
{
    /* Variable to define error */
    int8_t rslt;

    /* Variable to store sampling rate */
    uint8_t data = 0;

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);
    if ((rslt == BMI08X_OK) && (fifo_downs != NULL))
    {
        /* Read the accelerometer FIFO down data sampling rate */
        rslt = bmi08a_get_regs(BMI08X_FIFO_DOWNS_ADDR, &data, 1, dev);
        if (rslt == BMI08X_OK)
        {
            (*fifo_downs) = BMI08X_GET_BITS(data, BMI08X_ACC_FIFO_DOWNS);
        }
    }
    else
    {
        rslt = BMI08X_E_NULL_PTR;
    }

    return rslt;
}

/*!
 * @brief This API sets the down-sampling rates for accelerometer
 * FIFO data.
 *
 * @note Reduction of sample rate by a factor 2**fifo_downs
 */
int8_t bmi08a_set_fifo_down_sample(uint8_t fifo_downs, const struct bmi08x_dev *dev)
{
    /* Variable to define error */
    int8_t rslt;

    /* Variable to store sampling rate */
    uint8_t data = 0;

    /* Check for null pointer in the device structure */
    rslt = null_ptr_check(dev);
    if (rslt == BMI08X_OK)
    {
        /* Set the accelerometer FIFO down sampling rate */
        rslt = bmi08a_get_regs(BMI08X_FIFO_DOWNS_ADDR, &data, 1, dev);
        if (rslt == BMI08X_OK)
        {
            data = BMI08X_SET_BITS(data, BMI08X_ACC_FIFO_DOWNS, fifo_downs);
            rslt = bmi08a_set_regs(BMI08X_FIFO_DOWNS_ADDR, &data, 1, dev);
        }
    }

    return rslt;
}

/*****************************************************************************/
/* Static function definition */

/*!
 * @brief This API is used to validate the device structure pointer for
 * null conditions.
 */
static int8_t null_ptr_check(const struct bmi08x_dev *dev)
{
    int8_t rslt;

    if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_ms == NULL))
    {
        /* Device structure pointer is not valid */
        rslt = BMI08X_E_NULL_PTR;
    }
    else
    {
        /* Device structure is fine */
        rslt = BMI08X_OK;
    }

    return rslt;
}

/*!
 * @brief This API reads the data from the given register address.
 */

static int8_t get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint16_t index;
    uint16_t temp_len = len + dev->dummy_byte+5;
    uint8_t temp_buff[temp_len];

    if (dev->intf == BMI08X_SPI_INTF)
    {
        /* Configuring reg_addr for SPI Interface */
        reg_addr = reg_addr | BMI08X_SPI_RD_MASK;
    }

    /* Read the data from the register */
    rslt = dev->read(dev->accel_id, reg_addr, temp_buff, temp_len);

    if (rslt == BMI08X_OK)
    {
        for (index = 0; index < len; index++)
        {
            /* Updating the data buffer */
            reg_data[index] = temp_buff[index + dev->dummy_byte];
        }

    }
    else
    {
        /* Failure case */
        rslt = BMI08X_E_COM_FAIL;
    }

    return rslt;
}
//static int8_t get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const struct bmi08x_dev *dev)
//{
//    int8_t rslt;
//    uint16_t index;
//    uint16_t temp_len = len + dev->dummy_byte;
//    uint8_t temp_buff[temp_len];

//    if (dev->intf == BMI08X_SPI_INTF)
//    {
//        /* Configuring reg_addr for SPI Interface */
//        reg_addr = reg_addr | BMI08X_SPI_RD_MASK;
//    }

//    /* Read the data from the register */
//    rslt = dev->read(dev->accel_id, reg_addr, temp_buff, temp_len);

//    if (rslt == BMI08X_OK)
//    {
//        for (index = 0; index < len; index++)
//        {
//            /* Updating the data buffer */
//            reg_data[index] = temp_buff[index + dev->dummy_byte];
//        }
//    }
//    else
//    {
//        /* Failure case */
//        rslt = BMI08X_E_COM_FAIL;
//    }

//    return rslt;
//}

/*!
 * @brief This API writes the data to the given register address.
 */
static int8_t set_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const struct bmi08x_dev *dev)
{
    int8_t rslt;

    if (dev->intf == BMI08X_SPI_INTF)
    {
        /* Configuring reg_addr for SPI Interface */
        reg_addr = (reg_addr & BMI08X_SPI_WR_MASK);
    }

    /* write to an accel register */
    rslt = dev->write(dev->accel_id, reg_addr, reg_data, len);

    if (rslt != BMI08X_OK)
    {
        /* Updating the error status */
        rslt = BMI08X_E_COM_FAIL;
    }

    return rslt;
}

/*!
 * @brief This API configures the pins which fire the
 * interrupt signal when any interrupt occurs.
 */
static int8_t set_int_pin_config(const struct bmi08x_accel_int_channel_cfg *int_config, const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t reg_addr = 0, data, is_channel_invalid = FALSE;

    switch (int_config->int_channel)
    {
        case BMI08X_INT_CHANNEL_1:

            /* update reg_addr based on channel inputs */
            reg_addr = BMI08X_ACCEL_INT1_IO_CONF_REG;
            break;

        case BMI08X_INT_CHANNEL_2:

            /* update reg_addr based on channel inputs */
            reg_addr = BMI08X_ACCEL_INT2_IO_CONF_REG;
            break;

        default:
            is_channel_invalid = TRUE;
            break;
    }

    if (!is_channel_invalid)
    {
        /* Read interrupt pin configuration register */
        rslt = get_regs(reg_addr, &data, 1, dev);

        if (rslt == BMI08X_OK)
        {
            /* Update data with user configured bmi08x_int_cfg structure */
            data = BMI08X_SET_BITS(data, BMI08X_ACCEL_INT_LVL, int_config->int_pin_cfg.lvl);
            data = BMI08X_SET_BITS(data, BMI08X_ACCEL_INT_OD, int_config->int_pin_cfg.output_mode);

            if (int_config->int_type == BMI08X_ACCEL_SYNC_INPUT)
            {
                data = BMI08X_SET_BITS_POS_0(data, BMI08X_ACCEL_INT_EDGE, BMI08X_ENABLE);
                data = BMI08X_SET_BITS(data, BMI08X_ACCEL_INT_IN, int_config->int_pin_cfg.enable_int_pin);
                data = BMI08X_SET_BIT_VAL_0(data, BMI08X_ACCEL_INT_IO);
            }
            else
            {
                data = BMI08X_SET_BITS(data, BMI08X_ACCEL_INT_IO, int_config->int_pin_cfg.enable_int_pin);
                data = BMI08X_SET_BIT_VAL_0(data, BMI08X_ACCEL_INT_IN);
            }

            /* Write to interrupt pin configuration register */
            rslt = set_regs(reg_addr, &data, 1, dev);
        }
    }
    else
    {
        rslt = BMI08X_E_INVALID_INPUT;
    }

    return rslt;
}

/*!
 * @brief This API sets the data ready interrupt for accel sensor.
 */
static int8_t set_accel_data_ready_int(const struct bmi08x_accel_int_channel_cfg *int_config,
                                       const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data = 0, conf;

    /* Read interrupt map register */
    rslt = get_regs(BMI08X_ACCEL_INT1_INT2_MAP_DATA_REG, &data, 1, dev);

    if (rslt == BMI08X_OK)
    {
        conf = int_config->int_pin_cfg.enable_int_pin;

        switch (int_config->int_channel)
        {
            case BMI08X_INT_CHANNEL_1:

                /* Updating the data */
                data = BMI08X_SET_BITS(data, BMI08X_ACCEL_INT1_DRDY, conf);
                break;

            case BMI08X_INT_CHANNEL_2:

                /* Updating the data */
                data = BMI08X_SET_BITS(data, BMI08X_ACCEL_INT2_DRDY, conf);
                break;

            default:
                rslt = BMI08X_E_INVALID_INPUT;
                break;
        }

        if (rslt == BMI08X_OK)
        {
            /* Configure interrupt pins */
            rslt = set_int_pin_config(int_config, dev);

            if (rslt == BMI08X_OK)
            {
                /* Write to interrupt map register */
                rslt = set_regs(BMI08X_ACCEL_INT1_INT2_MAP_DATA_REG, &data, 1, dev);
            }
        }
    }

    return rslt;
}

/*!
 * @brief This API sets the synchronized data ready interrupt for accel sensor
 */
static int8_t set_accel_sync_data_ready_int(const struct bmi08x_accel_int_channel_cfg *int_config,
                                            const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data, reg_addr = 0;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);
    if (rslt == BMI08X_OK)
    {

        data = BMI08X_ACCEL_INTA_DISABLE;

        switch (int_config->int_channel)
        {
            case BMI08X_INT_CHANNEL_1:
                reg_addr = BMI08X_ACCEL_INT1_MAP_REG;
                break;

            case BMI08X_INT_CHANNEL_2:
                reg_addr = BMI08X_ACCEL_INT2_MAP_REG;
                break;

            default:
                rslt = BMI08X_E_INVALID_INPUT;
                break;
        }

        if (rslt == BMI08X_OK)
        {
            if (int_config->int_pin_cfg.enable_int_pin == BMI08X_ENABLE)
            {
                /*interrupt A mapped to INT1/INT2 */
                data = BMI08X_ACCEL_INTA_ENABLE;
            }

            /* Write to interrupt map register */
            rslt = set_regs(reg_addr, &data, 1, dev);

            if (rslt == BMI08X_OK)
            {
                /*set input interrupt configuration*/
                rslt = set_int_pin_config(int_config, dev);
            }
        }
    }

    return rslt;
}

/*!
 * @brief This API configures the given interrupt channel as input for accel sensor
 */
static int8_t set_accel_sync_input(const struct bmi08x_accel_int_channel_cfg *int_config, const struct bmi08x_dev *dev)
{
    int8_t rslt;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);
    if (rslt == BMI08X_OK)
    {
        /*set input interrupt configuration*/
        rslt = set_int_pin_config(int_config, dev);
    }

    return rslt;
}

/*!
 * @brief This API sets the anymotion interrupt for accel sensor
 */
static int8_t set_accel_anymotion_int(const struct bmi08x_accel_int_channel_cfg *int_config,
                                      const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data, reg_addr = 0;

    /* Check for null pointer in the device structure*/
    rslt = null_ptr_check(dev);
    if (rslt == BMI08X_OK)
    {

        data = BMI08X_ACCEL_INTB_DISABLE;

        switch (int_config->int_channel)
        {
            case BMI08X_INT_CHANNEL_1:
                reg_addr = BMI08X_ACCEL_INT1_MAP_REG;
                break;

            case BMI08X_INT_CHANNEL_2:
                reg_addr = BMI08X_ACCEL_INT2_MAP_REG;
                break;

            default:
                rslt = BMI08X_E_INVALID_INPUT;
                break;
        }

        if (rslt == BMI08X_OK)
        {
            if (int_config->int_pin_cfg.enable_int_pin == BMI08X_ENABLE)
            {
                /*interrupt B mapped to INT1/INT2 */
                data = BMI08X_ACCEL_INTB_ENABLE;
            }

            /* Write to interrupt map register */
            rslt = set_regs(reg_addr, &data, 1, dev);

            if (rslt == BMI08X_OK)
            {
                /*set input interrupt configuration*/
                rslt = set_int_pin_config(int_config, dev);
            }
        }
    }

    return rslt;
}

/*!
 *  @brief This API writes the config stream data in memory using burst mode.
 */
static int8_t stream_transfer_write(const uint8_t *stream_data, uint16_t index, const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t asic_msb = (uint8_t)((index / 2) >> 4);
    uint8_t asic_lsb = ((index / 2) & 0x0F);

    /* Write to feature config register */
    rslt = set_regs(BMI08X_ACCEL_RESERVED_5B_REG, &asic_lsb, 1, dev);
    if (rslt == BMI08X_OK)
    {
        /* Write to feature config register */
        rslt = set_regs(BMI08X_ACCEL_RESERVED_5C_REG, &asic_msb, 1, dev);

        if (rslt == BMI08X_OK)
        {
            /* Write to feature config registers */
            rslt = set_regs(BMI08X_ACCEL_FEATURE_CFG_REG, (uint8_t *)stream_data, dev->read_write_len, dev);
        }
    }

    return rslt;
}

/*!
 * @brief This API performs the pre-requisites needed to perform the self test
 */
static int8_t enable_self_test(struct bmi08x_dev *dev)
{
    int8_t rslt;

    /* Configuring sensors to perform accel self test */
    dev->accel_cfg.odr = BMI08X_ACCEL_ODR_1600_HZ;
    dev->accel_cfg.bw = BMI08X_ACCEL_BW_NORMAL;

    /*check the chip id of the accel variant and assign the range */
#if BMI08X_FEATURE_BMI085 == 1
    dev->accel_cfg.range = BMI085_ACCEL_RANGE_16G;
#elif BMI08X_FEATURE_BMI088 == 1
    dev->accel_cfg.range = BMI088_ACCEL_RANGE_24G;
#endif

    dev->accel_cfg.power = BMI08X_ACCEL_PM_ACTIVE;

    /* Enable Accel sensor */
    rslt = bmi08a_set_power_mode(dev);
    if (rslt == BMI08X_OK)
    {
        /* Configure sensors with above configured settings */
        rslt = bmi08a_set_meas_conf(dev);

        if (rslt == BMI08X_OK)
        {
            /* Self test delay */
            dev->delay_ms(BMI08X_SELF_TEST_DELAY_MS);
        }
    }

    return rslt;
}

/*!
 * @brief This API reads the accel data with the positive excitation
 */
static int8_t positive_excited_accel(struct bmi08x_sensor_data *accel_pos, const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t reg_data = BMI08X_ACCEL_POSITIVE_SELF_TEST;

    /* Enable positive excitation for all 3 axes */
    rslt = set_regs(BMI08X_ACCEL_SELF_TEST_REG, &reg_data, 1, dev);
    if (rslt == BMI08X_OK)
    {
        /* Read accel data after 50ms delay */
        dev->delay_ms(BMI08X_SELF_TEST_DATA_READ_MS);
        rslt = bmi08a_get_data(accel_pos, dev);
    }

    return rslt;
}

/*!
 * @brief This API reads the accel data with the negative excitation
 */
static int8_t negative_excited_accel(struct bmi08x_sensor_data *accel_neg, const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t reg_data = BMI08X_ACCEL_NEGATIVE_SELF_TEST;

    /* Enable negative excitation for all 3 axes */
    rslt = set_regs(BMI08X_ACCEL_SELF_TEST_REG, &reg_data, 1, dev);
    if (rslt == BMI08X_OK)
    {
        /* Read accel data after 50ms delay */
        dev->delay_ms(BMI08X_SELF_TEST_DATA_READ_MS);
        rslt = bmi08a_get_data(accel_neg, dev);

        if (rslt == BMI08X_OK)
        {
            /* Disable self test */
            reg_data = BMI08X_ACCEL_SWITCH_OFF_SELF_TEST;
            rslt = set_regs(BMI08X_ACCEL_SELF_TEST_REG, &reg_data, 1, dev);
        }
    }

    return rslt;
}

/*!
 * @brief This API validates the self test results
 */
static int8_t validate_accel_self_test(const struct bmi08x_sensor_data *accel_pos,
                                       const struct bmi08x_sensor_data *accel_neg)
{
    int8_t rslt;

    /*! Structure for difference of accel values in g */
    struct selftest_delta_limit accel_data_diff = { 0 };

    /*! Structure for difference of accel values in mg */
    struct selftest_delta_limit accel_data_diff_mg = { 0 };

    accel_data_diff.x = (uint16_t) (BMI08X_ABS(accel_pos->x) + BMI08X_ABS(accel_neg->x));
    accel_data_diff.y = (uint16_t) (BMI08X_ABS(accel_pos->y) + BMI08X_ABS(accel_neg->y));
    accel_data_diff.z = (uint16_t) (BMI08X_ABS(accel_pos->z) + BMI08X_ABS(accel_neg->z));

    /*! Converting LSB of the differences of
     * accel values to mg */
    convert_lsb_g(&accel_data_diff, &accel_data_diff_mg);

    /* Validating accel data by comparing with minimum value of the axes in mg */
    /* x axis limit 1000mg, y axis limit 1000mg and z axis limit 500mg */
    if (accel_data_diff_mg.x >= 1000 && accel_data_diff_mg.y >= 1000 && accel_data_diff_mg.z >= 500)
    {
        /* Updating Okay status */
        rslt = BMI08X_OK;
    }
    else
    {
        /* Updating Error status */
        rslt = BMI08X_W_SELF_TEST_FAIL;
    }

    return rslt;
}

/*!
 *  @brief This API converts lsb value of axes to mg for self-test.
 */
static void convert_lsb_g(const struct selftest_delta_limit *accel_data_diff,
                          struct selftest_delta_limit *accel_data_diff_mg)
{
    /* accel x value in mg */
    accel_data_diff_mg->x = (uint16_t) ((accel_data_diff->x / (int32_t)LSB_PER_G) * 1000);

    /* accel y value in mg */
    accel_data_diff_mg->y = (uint16_t) ((accel_data_diff->y / (int32_t)LSB_PER_G) * 1000);

    /* accel z value in mg */
    accel_data_diff_mg->z = (uint16_t) ((accel_data_diff->z / (int32_t)LSB_PER_G) * 1000);
}

/*!
 * @brief This internal API is used to parse and store the skipped frame count
 * from the FIFO data.
 */
static int8_t unpack_skipped_frame(uint16_t *data_index, struct bmi08x_fifo_frame *fifo)
{
    /* Variables to define error */
    int8_t rslt = BMI08X_OK;

    /* Validate data index */
    if ((*data_index) >= fifo->length)
    {
        /* Update the data index to the last byte */
        (*data_index) = fifo->length;

        /* FIFO is empty */
        rslt = BMI08X_W_FIFO_EMPTY;
    }
    else
    {
        /* Update skipped frame count in the FIFO structure */
        fifo->skipped_frame_count = fifo->data[(*data_index)];

        /* Move the data index by 1 byte */
        (*data_index) = (*data_index) + 1;

        /* More frames could be read */
        rslt = BMI08X_W_PARTIAL_READ;
    }

    return rslt;
}

/*!
 * @brief This internal API is used to reset the FIFO related configurations in
 * the FIFO frame structure for the next FIFO read.
 */
static void reset_fifo_frame_structure(struct bmi08x_fifo_frame *fifo)
{
    /* Reset FIFO data structure */
    fifo->acc_byte_start_idx = 0;
    fifo->sensor_time = 0;
    fifo->skipped_frame_count = 0;
}

/*!
 * @brief This internal API is used to parse accelerometer data from the
 * FIFO data.
 */
static void unpack_accel_data(struct bmi08x_sensor_data *acc,
                              uint16_t data_start_index,
                              const struct bmi08x_fifo_frame *fifo)
{
    /* Variables to store LSB value */
    uint16_t data_lsb;

    /* Variables to store MSB value */
    uint16_t data_msb;

    /* Accelerometer raw x data */
    data_lsb = fifo->data[data_start_index++];
    data_msb = fifo->data[data_start_index++];
    acc->x = (int16_t)((data_msb << 8) | data_lsb);

    /* Accelerometer raw y data */
    data_lsb = fifo->data[data_start_index++];
    data_msb = fifo->data[data_start_index++];
    acc->y = (int16_t)((data_msb << 8) | data_lsb);

    /* Accelerometer raw z data */
    data_lsb = fifo->data[data_start_index++];
    data_msb = fifo->data[data_start_index++];
    acc->z = (int16_t)((data_msb << 8) | data_lsb);

}

/*!
 * @brief This internal API is used to parse the accelerometer data from the
 * FIFO data in header mode. It updates the current data
 * byte to be parsed.
 */
static int8_t unpack_accel_frame(struct bmi08x_sensor_data *acc,
                                 uint16_t *idx,
                                 uint16_t *acc_idx,
                                 uint16_t frame,
                                 const struct bmi08x_fifo_frame *fifo)
{
    /* Variable to define error */
    int8_t rslt = BMI08X_OK;

    switch (frame)
    {
        /* If frame contains only accelerometer data */
        case BMI08X_FIFO_HEADER_ACC_FRM:

            /* Partially read, then skip the data */
            if (((*idx) + fifo->acc_frm_len) > fifo->length)
            {
                /* Update the data index as complete*/
                (*idx) = fifo->length;

                /* FIFO is empty */
                rslt = BMI08X_W_FIFO_EMPTY;
                break;
            }

            /* Get the accelerometer data */
            unpack_accel_data(&acc[(*acc_idx)], *idx, fifo);

            /* Update data index */
            (*idx) = (*idx) + BMI08X_FIFO_ACCEL_LENGTH;

            /* Update accelerometer frame index */
            (*acc_idx)++;

            break;
        default:

            /* Move the data index to the last byte in case of invalid values */
            (*idx) = fifo->length;

            /* FIFO is empty */
            rslt = BMI08X_W_FIFO_EMPTY;
            break;
    }

    return rslt;
}

/*!
 * @brief This internal API is used to move the data index ahead of the
 * current_frame_length parameter when unnecessary FIFO data appears while
 * extracting the user specified data.
 */
static int8_t move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bmi08x_fifo_frame *fifo)
{
    /* Variables to define error */
    int8_t rslt = BMI08X_OK;

    /* Validate data index */
    if (((*data_index) + current_frame_length) > fifo->length)
    {
        /* Move the data index to the last byte */
        (*data_index) = fifo->length;

        /* FIFO is empty */
        rslt = BMI08X_W_FIFO_EMPTY;
    }
    else
    {
        /* Move the data index to next frame */
        (*data_index) = (*data_index) + current_frame_length;

    }

    return rslt;
}

/*!
 * @brief This internal API is used to parse and store the sensor time from the
 * FIFO data.
 */
static int8_t unpack_sensortime_frame(uint16_t *data_index, struct bmi08x_fifo_frame *fifo)
{
    /* Variables to define error */
    int8_t rslt = BMI08X_OK;

    /* Variables to define 3 bytes of sensor time */
    uint32_t sensor_time_byte3 = 0;
    uint16_t sensor_time_byte2 = 0;
    uint8_t sensor_time_byte1 = 0;

    /* Validate data index */
    if (((*data_index) + BMI08X_SENSOR_TIME_LENGTH) > fifo->length)
    {
        /* Move the data index to the last byte */
        (*data_index) = fifo->length;

        /* FIFO is empty */
        rslt = BMI08X_W_FIFO_EMPTY;
    }
    else
    {
        /* Get sensor time from the FIFO data */
        sensor_time_byte3 = fifo->data[(*data_index) + BMI08X_SENSOR_TIME_MSB_BYTE] << 16;
        sensor_time_byte2 = fifo->data[(*data_index) + BMI08X_SENSOR_TIME_XLSB_BYTE] << 8;
        sensor_time_byte1 = fifo->data[(*data_index)];

        /* Update sensor time in the FIFO structure */
        fifo->sensor_time = (uint32_t)(sensor_time_byte3 | sensor_time_byte2 | sensor_time_byte1);

        /* Move the data index by 3 bytes */
        (*data_index) = (*data_index) + BMI08X_SENSOR_TIME_LENGTH;

    }

    return rslt;
}

/*!
 * @brief This internal API is used to parse the accelerometer data from the
 * FIFO in header mode.
 */
static int8_t extract_acc_header_mode(struct bmi08x_sensor_data *acc,
                                      uint16_t *accel_length,
                                      struct bmi08x_fifo_frame *fifo,
                                      const struct bmi08x_dev *dev)
{
    /* Variable to define error */
    int8_t rslt = BMI08X_OK;

    /* Variable to define header frame */
    uint8_t frame_header = 0;

    /* Variable to index the data bytes */
    uint16_t data_index;

    /* Variable to index accelerometer frames */
    uint16_t accel_index = 0;

    /* Variable to indicate accelerometer frames read */
    uint16_t frame_to_read = *accel_length;

    /* Check if this is the first iteration of data unpacking
     * if yes, then consider dummy byte on SPI
     */
    if (fifo->acc_byte_start_idx == 0)
    {
        fifo->acc_byte_start_idx = dev->dummy_byte;
    }
    for (data_index = fifo->acc_byte_start_idx; data_index < fifo->length;)
    {
        /* Get frame header byte */
        frame_header = fifo->data[data_index];

        /* Index shifted to next byte where data starts */
        data_index++;
        switch (frame_header)
        {
            /* If header defines accelerometer frame */
            case BMI08X_FIFO_HEADER_ACC_FRM:
            case BMI08X_FIFO_HEADER_ALL_FRM:

                /* Unpack from normal frames */
                rslt = unpack_accel_frame(acc, &data_index, &accel_index, frame_header, fifo);
                break;

            /* If header defines sensor time frame */
            case BMI08X_FIFO_HEADER_SENS_TIME_FRM:
                rslt = unpack_sensortime_frame(&data_index, fifo);
                break;

            /* If header defines skip frame */
            case BMI08X_FIFO_HEADER_SKIP_FRM:
                rslt = unpack_skipped_frame(&data_index, fifo);
                break;

            /* If header defines Input configuration frame */
            case BMI08X_FIFO_HEADER_INPUT_CFG_FRM:
                rslt = move_next_frame(&data_index, BMI08X_FIFO_INPUT_CFG_LENGTH, fifo);
                break;

             /* If header defines sample drop frame */
            case BMI08X_FIFO_SAMPLE_DROP_FRM:
            	rslt = move_next_frame(&data_index, BMI08X_FIFO_INPUT_CFG_LENGTH, fifo);
            	break;

            /* If header defines invalid frame or end of valid data */
            case BMI08X_FIFO_HEAD_OVER_READ_MSB:

                /* Move the data index to the last byte to mark completion */
                data_index = fifo->length;

                /* FIFO is empty */
                rslt = BMI08X_W_FIFO_EMPTY;
                break;
            default:

                /* Move the data index to the last byte in case of invalid values */
                data_index = fifo->length;

                /* FIFO is empty */
                rslt = BMI08X_W_FIFO_EMPTY;
                break;
        }

        /* Break if Number of frames to be read is complete or FIFO is mpty */
        if ((frame_to_read == accel_index) || (rslt == BMI08X_W_FIFO_EMPTY))
        {
            break;
        }
    }

    /* Update the accelerometer frame index */
    (*accel_length) = accel_index;

    /* Update the accelerometer byte index */
    fifo->acc_byte_start_idx = data_index;

    return rslt;
}

/*!
 * @brief This API sets the FIFO water mark interrupt for accel sensor.
 */
static int8_t set_fifo_wm_int(const struct bmi08x_accel_int_channel_cfg *int_config, const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data = 0, conf;

    /* Read interrupt map register */
    rslt = get_regs(BMI08X_ACCEL_INT1_INT2_MAP_DATA_REG, &data, 1, dev);

    if (rslt == BMI08X_OK)
    {
        conf = int_config->int_pin_cfg.enable_int_pin;

        switch (int_config->int_channel)
        {
            case BMI08X_INT_CHANNEL_1:

                /* Updating the data */
                data = BMI08X_SET_BITS(data, BMI08X_ACCEL_INT1_FWM, conf);
                break;

            case BMI08X_INT_CHANNEL_2:

                /* Updating the data */
                data = BMI08X_SET_BITS(data, BMI08X_ACCEL_INT2_FWM, conf);
                break;

            default:
                rslt = BMI08X_E_INVALID_INPUT;
                break;
        }

        if (rslt == BMI08X_OK)
        {
            /* Configure interrupt pins */
            rslt = set_int_pin_config(int_config, dev);

            if (rslt == BMI08X_OK)
            {
                /* Write to interrupt map register */
                rslt = set_regs(BMI08X_ACCEL_INT1_INT2_MAP_DATA_REG, &data, 1, dev);
            }
        }
    }

    return rslt;
}

/*!
 * @brief This API sets the FIFO full interrupt for accel sensor.
 */
static int8_t set_fifo_full_int(const struct bmi08x_accel_int_channel_cfg *int_config, const struct bmi08x_dev *dev)
{
    int8_t rslt;
    uint8_t data = 0, conf;

    /* Read interrupt map register */
    rslt = get_regs(BMI08X_ACCEL_INT1_INT2_MAP_DATA_REG, &data, 1, dev);

    if (rslt == BMI08X_OK)
    {
        conf = int_config->int_pin_cfg.enable_int_pin;

        switch (int_config->int_channel)
        {
            case BMI08X_INT_CHANNEL_1:

                /* Updating the data */
                data = BMI08X_SET_BITS_POS_0(data, BMI08X_ACCEL_INT1_FFULL, conf);
                break;

            case BMI08X_INT_CHANNEL_2:

                /* Updating the data */
                data = BMI08X_SET_BITS(data, BMI08X_ACCEL_INT2_FFULL, conf);
                break;

            default:
                rslt = BMI08X_E_INVALID_INPUT;
                break;
        }

        if (rslt == BMI08X_OK)
        {
            /* Configure interrupt pins */
            rslt = set_int_pin_config(int_config, dev);

            if (rslt == BMI08X_OK)
            {
                /* Write to interrupt map register */
                rslt = set_regs(BMI08X_ACCEL_INT1_INT2_MAP_DATA_REG, &data, 1, dev);
            }
        }
    }

    return rslt;
}

/** @}*/
